How can an unused variable can be indicative of bug(s)? [closed] - recycle-bin

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
Language type doesn't matter here; it can be functional; procedural, imperative, object oriented... or it doesn't have to be the case in a language at all. This question applies to the language that can have unused variable/code.
What type of this bug will be? How does not using something extra qualify as a bug?
A little background: though I read it on F# blog, it seems like language agnostic to me; after all you can have unused variable in any program in any language.

The case where I've actually seen a warning for unused variables (or unused parameters) catch a bug is something like this:
start = 1
stop = 10
do_something(start, start, other_data)
stop is unused, because I typed the wrong thing, and luckily the warning would lead me to identify the bug. Obviously there are other ways to catch that bug (testing), and there are instances of that bug that wouldn't be caught this way because the variable is still used elsewhere.
Generally an unused variable is just a warning that the code isn't written as the author really intended (because normally you don't want an unused variable). Doesn't necessarily mean it's buggy, just that you might like to write it differently.

Here's an example where an unused variable may mask a bug until the unused variable is removed:
int a[10];
int b[10]; // unused
int c[10];
// initialise a
for (i = 0; i <= 10; ++i)
a[i] = i; // out of bounds write to a when i = 10
In the above case the out of bounds write to a happens to overwrite the start of an unused array (b) and so doesn't have any harmful effects (this is known as a latent bug). When the unused array is removed then the start of c gets overwritten instead.
(Note that the above example is compiler-dependent - it assumes that b doesn't get optimised away by a smart compiler and that arrays are allocated sequentially and contiguously, but the general principle is nonetheless valid.)

Since, I have never written functions/methods longer than 100 lines, I don't know when or how following things happen but some scenarios I can think of involve:
There can be code that has been modified; now useless.
There can be code that is just dead because of many such modifications. Dead code is problematic in large code base; as programmer has to read it almost every time and can't tweak (remove) it because then he would require a serious bug testing. Tweaking code for bugs produces bugs of other type.
Unused variable shows the lack of planning or implementing. Initially required by specification but now still unused because of further delay or because specification stayed same.
May be an interface kind of thing implemented too early too soon. Now, API is public...
In language that has preprocessor (sort of) directives that can modify code based on the environment or type of build; a lot of variables can be unused. like Debug and Release conditions in C#. That can be marked as a bug, as in "it might be a bug in different build or condition"
Other than that, I am still looking for answers.

Related

Objective-C multiple pointers to same object? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Ive searched around and can't find any answers that aren't related to C++, which isn't the exact same thing. I have a game and I keep an NSMutableArray of my sprites for certain categories because there are too many of them and they appear/dissapear too often to keep references to every single one of them, and also the number of them varies. so they are stored in an array.
In my didBeginContact method I grab the contact.bodyA.node object and pass it into a mehtod I've written called getSprite which enumerates over the array of objects I have, finds the one that matches and returns that one as an SKSpriteNode so I can use SKSpriteNode-specific methods such as animateWithFrames and such. However, I use this method pretty frequently and I'm wondering if doing something like:
SKSpriteNode *sprite = (SKSpriteNode*)[contact.bodyB.node parent];
Is acceptable as well, and then just using that pointer to refer to my object. It works, but I don't know if it will cause memory leaks or other problems. Any suggestions? (the reason I used the parent method is because the sprite I'm actually after is the parent of the one involved in the collision).
I assume you're using ARC. The local pointer to the object is a strong pointer by default, since you didn't specify anything differently. So that object is guaranteed to not be destroyed during the scope in which your local sprite pointer exists. It will not maintain a strong reference beyond that scope. The NSMutableArray also maintains a strong reference to to the objects it contains, so while they are in that array, the objects will not be destroyed.
As far as memory leaks go, this shouldn't cause any problems. It should also be more performant since it's a direct link back up to the sprite, rather than iterating and searching for the correct sprite. I don't see any reason why you couldn't do that, besides the fact that is might affect future plans for your game since the parent relationship of the object becomes part of the logic when is probably shouldn't be, but if you centralize that code so it's easy to change if you ever change the hierarchy of your sprites it should be fine.

Calling functions in C-like syntax [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
How can I write code in Xcode max similar to syntax in Java or C++ in particular call functions (messages), static or dynamic? I just want to simply call Objective-C function in C-like syntax.
How to when I write NSString * s = NSString.alloc().init();
(or similar, for example, NSString::alloc().init(), or NSString::alloc.init or (new NSString()).alloc().init() ;))
in Xcode (or another iPhone dev environment), the compiler did not cause an error and it will run.
or code like
NSString * a = NSString.alloc().init(); //or similar
bool b = a.compare("abcdef"); //or bool b = a->compare("abcdef");
will run.
?
Objective-C has C functions. In fact, all valid C code is valid Objective-C code. So yes, you can call functions with C syntax.
However, objects and message sends use Objective-C's syntactic extensions to C, which are not configurable. They are part of the language. You can't change Objective-C's syntax any more than you could make C++ use Smalltalk syntax.
No, there is no way to call Objective-C methods in a different syntax, with one exception:
You can call methods that do not take arguments with a dot notation as in object.method (this is mostly used with properties, which in turn are getter and setter methods that are generated by the compiler).
So the way methods are called in Objective-C ([object method] or [object methodWithArgumentA:someValue argumentB:otherValue]) cannot be changed. This is the syntax chosen by the language designers. And once you've worked with it a little, you'll understand why:
Method names in Objective-C tend to be very descriptive and are used as if Objective-C had named arguments (technically, that's not the case). Like:
[someData writeToFile:aFileName atomically:YES];
How would you transfer this to a dot notation? It might look like this:
someData.writeToFileAtomically(aFileName, YES);
Now, if I see a method just writeToFileAtomically I wouldn't be surprised if it just would take one argument (whether to atomically write to file; but which file?) or no argument (just write to a file atomically; again, which file?). With the Objective-C notation the intention is more clear.
And now consider object.addObserverForKeyPathOptionsContext(o, k, op, c) vs. [object addObserver:o forKeypath:k options:op context:c].
Whether one likes this syntax or not is subjective. You don't seem to like it, as you wouldn't have asked how to get rid of it. But if you want to write Objective-C code you'll have to accept that this is the way it's done and you cannot change it. Embrace it, I found it weird at first as well (also coming from a long C++ and Java background) but now I miss the very verbose way of calling methods with arguments of Objective-C when working in other languages.

Objective C's ARC vs C++'s Manual Memory Management [duplicate]

This question already has answers here:
What are the advantages and disadvantages of using ARC? [closed]
(4 answers)
Closed 9 years ago.
One possible exam question reads as follows:
"Explain the benefits and drawbacks of Objective C's memory management when compared to c++'s"
I do know Objective C uses ARC, and ARC enables us to avoid destroying an object that is still being referenced by something else (meaning, its still needed). But I can't find any drawbacks at all, anywhere. I can only think of "There are no drawbacks" as an answer, but since the question explicitly asks for drawbacks, I'm guessing there must be at least one.
Reference counting may solve a problem that you don't have. It comes at a price, and you'll end up paying the price no matter whether you wanted the solution in the first place.
Contrary to what the gut feeling may say, most objects actually don't need to be shared at all and have a well-defined, unique ownership throughout their life. All that's needed is the ability to pass those objects around; reference counting provides that, but it provides much more, and has a greater cost.
(This answer compares reference counting in Objective C to C++-style lifetime management. It does not consider whether reference counting in Obj-C is sensible in the first place. ARC is simply an automated form of MRC, and if you were using MRC in the past and it made sense, then the question whether to migrate to ARC is not the point of this post. Rather, this post applies equally to the comparison of "MRC in Obj-C vs C++".)
Reference counting 'frees' you from always thinking about WHEN to delete an object. Anybody using the object just says, I still need it (want to retain it) or I am done with it (I release it)
that makes memory management way easier and also makes the code more manageable
BUT
it comes at the price of 2 additional method calls whenever you pass stuff around: you have to retain the object, THEN save the pointer and later also call release it.
When you deal with LOTS of objects that become a real life problem. Just the extra calls can kill your algorithms performance
and especially if you don't need any reference counting because the scope where the object is used is clear, the overhead is just annoying.
so it is convenience + maintainability vs. speed

Implicit data members for #synthesize - good practice or bad habit? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
Today, I got a link to a long list of coding guidelines, proclaiming to be "code commandments". A good read, and full of new insights to me. Among the list, somewhere along 25% of the scrollbar, I come across something new to me: Implicit data member creation.
Although every tutorial, book and video I've read or watched about Objective-C always performs the triad of NSNumber *number | #property NSNumber *number | #synthesize number, these commandments now tell me I can simply omit the first step (data member declaration in the interface) because #synthesize will create one on the fly. Say what!?
With a little disbelief I deleted several of my data member declarations, and indeed, my app still works like a charm. Less typing, less reading, less chance for typos.
Sounds to me like a win-win-win, but is it really good practice?
I'm asking this question out of pure disbelief that all the tutorials, books and videos are teaching the wrong lesson, at least too much of it, or that I've been not paying attention in class...
Cheers,
EP.
Edit: Although I copied the expression "data member" from the linked post, it is more commonly described with the word "ivar", just a good one to have in here for search friendliness. This also takes care of my former confusion over property/ivar/member naming :).
Synthesized instance variables are a feature of the modern Objective-C 2.0 runtime. This means they're available on x86_64, on ARM, and as of Xcode 3.2, on the iPhone Simulator. It means exactly what you suggested - you can omit the ivar declaration, and the #synthesize line will generate the ivar for you. The performance of this is exactly the same as declaring the ivar explicitly, but it has the very important benefit of not polluting your header file with private implementation details.
I have begun the practice of removing synthesized properties from the Objective-C classes I create. The primary reason for this is because there is a distinct difference between:
self.myNSObject = [NSObject new];
and
myNSObject = [NSObject new];
Specifically, if myNSObject is declared as a #property(retain, ...) the former line will result in a retainCount of 2 while the latter will result in a retainCount of 1. This means that unless you are extremely careful about every assignment to myNSObject you run the risk of getting your retain/release balancing wrong.
The other reasons you specify are also very valid. There is a lot going on in the synthesized routines that my brain doesn't account for when I'm reading the code I've written, so a lot is taking place behind the scenes that I'm not thinking of yet am accountable for. It's for very a similar reason I've abandoned Apple's Interface Builder.

Best way to handle and report memory allocation errors due to integer overflow in Objective-C?

To begin with, let me say that I understand how and why the problem I'm describing can happen. I was a Computer Science major, and I understand overflow/underflow and signed/unsigned arithmetic. (For those unfamiliar with the topic, Apple's Secure Coding Guide discusses integer overflow briefly.)
My question is about reporting and recovering from such an error once it has been detected, and more specifically in the case of an Objective-C framework. (I write and maintain CHDataStructures.) I have a few collections classes that allocate memory for storing objects and dynamically expand as necessary. I haven't yet seen any overflow-related crashes, probably because my test cases mostly use sane data. However, given unvalidated values, things could explode rather quickly, and I want to prevent that.
I have identified at least two common cases where this can occur:
The caller passes a very large unsigned value (or negative signed value) to -initWithCapacity:.
Enough objects have been added to cause the capacity to dynamically expand, and the capacity has grown large enough to cause overflow.
The easy part is detecting whether overflow will occur. (For example, before attempting to allocate length * sizeof(void*) bytes, I can check whether length <= UINT_MAX / sizeof(void*), since failing this test will mean that the product will overflow and potentially allocate a much smaller region of memory than desired. On platforms that support it, the checkint.h API is another alternative.) The harder part is determining how to deal with it gracefully. In the first scenario, the caller is perhaps better equipped (or at least in the mindset) to deal with a failure. The second scenario can happen anywhere in the code that an object is added to the collection, which may be quite non-deterministic.
My question, then, is this: How is "good citizen" Objective-C code expected to act when integer overflow occurs in this type of situation? (Ideally, since my project is a framework in the same spirit as Foundation in Cocoa, I'd like to model off of the way it behaves for maximum "impedance matching". The Apple documentation I've found doesn't mention much at all about this.) I figure that in any case, reporting the error is a given. Since the APIs to add an object (which could cause scenario 2) don't accept an error parameter, what can I really do to help resolve the problem, if anything? What is really considered okay in such situations? I'm loath to knowingly write crash-prone code if I can do better...
Log and raise an exception.
You can only really be a good citizen to other programmers, not the end user, so pass the problem upstairs and do it in a way that clearly explains what is going on, what the problem is (give numbers) and where it is happening so the root cause can be removed.
There are two issues at hand:
(1) An allocation has failed and you are out of memory.
(2) You have detected an overflow or other erroneous condition that will lead to (1) if you continue.
In the case of (1), you are hosed (unless the failed allocation was both stupid large & you know that the failed allocation was only that one). If this happens, the best thing you can do is to crash as quickly as possible and leave behind as much evidence as you can. In particular, creating a function that calls abort() of a name like IAmCrashingOnPurposeBecauseYourMemoryIsDepleted() will leave evidence in the crash log.
If it is really (2), then there are additional questions. Specifically, can you recover from the situation and, regardless, is the user's data still intact? If you can recover, then grand... do so and the user never has to know. If not, then you need to make absolutely sure that the user's data is not corrupt. If it isn't, then save and die. If the user's data is corrupt, then do your best to not persist the corrupted data and let the user know that something has gone horribly wrong. If the user's data is already persisted, but corrupt, then... well... ouch... you might want to consider creating a recovery tool of some kind.
With regards to dynamically growing, array-based storage, there's only so much that can be done. I'm a developer on the Moab scheduler for supercomputers, and we also deal with very large numbers on systems with thousands of processors, thousands of jobs, and massive amounts of job output. At some point, you can't declare a buffer to be any bigger, without creating a whole new data-type to deal with sizes larger than UINT_MAX, or LONG_LONG_MAX etc., at which point on most "normal" machines you'll be running out of stack/heap space anyway. So I'd say log a meaningful error-message, keep the collection from exploding, and if the user needs to add that many things to a CHDataStructures collection, they ought to know that there are issues dealing with very large numbers, and the caller ought to check whether the add was successful (keep track of the size of the collection, etc.).
Another possibility is to convert array-based storage to dynamically allocated, linked-list-based storage when you get to the point when you can't allocate a larger array with an unsigned int or unsigned long. This would be expensive, but would happen rarely enough that it shouldn't be terribly noticeable to users of the framework. Since the limit on the size of a dynamically allocated, linked-list-based collection is the size of the heap, any user that added enough items to a collection to "overflow" it then would have bigger problems than whether or not his item was successfully added.
I'd say the correct thing to do would be to do what the Cocoa collections do. For example, if I have the following code:
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSMutableArray * a = [[NSMutableArray alloc] init];
for (uint32_t i = 0; i < ULONG_MAX; ++i) {
for (uint32_t i = 0; i < 10000000; ++i) {
[a addObject:#"foo"];
}
NSLog(#"%lu rounds of 10,000,000 completed", i+1);
}
[a release];
[pool drain];
return 0;
}
..and just let it run, it will eventually die with EXC_BAD_ACCESS. (I compiled and ran this as a 32-bit app so I could be sure to run out of space when I hit 2**32 objects.
In other words, throwing an exception would be nice, but I don't think you really have to do anything.
Using assertions and a custom assertion handler may be the best available option for you.
With assertions, you could easily have many checkpoints in your code, where you verify that things work as they should. If they don't, by default the assertion macro logs the error (developer-defined string), and throws an exception. You can also override the default behavior using a custom assertion handler and implement a different way to handle error conditions (even avoid throwing exceptions).
This approach allows for a greater degree of flexibility and you can easily modify your error handling strategy (throwing exceptions vs. dealing with errors internally) at any point.
The documentation is very concise: Assertions and Logging.