Reputation: 1243
I've seen lots of code like this:
SomeType* ptr = NULL;
ptr = SomeMethod(some, params);
What's the point? I've also seen it where ptr
is declared somewhere else (for example in a class definition) and then in the class constructor there'd be this:
ptr = NULL;
ptr = SomeMethod(some, params);
I don't understand why this is done. Surely the ptr = NULL
line is useless?
Upvotes: 24
Views: 1102
Reputation: 58560
The code is useless as it stands now, but perhaps the use anticipates future maintenance in which more lines will be added between the redundant initialization and assignment such that the initialization is no longer redundant.
The code may also have been the result of a deletion. That is, perhaps some code existed between the declaration and assignment, but was since removed, and no cleanup was done to merge the assignment into the initialization. Of course, there is no point to the code being the way it is; in this situation, we just have a historical explanation about how it got that way (and perhaps justification to change it).
Sometimes seemingly useless variable initializations occur as the result of someone having had to silence a compiler warning about a "potentially unused" variable, which can happen if there is more than one way to reach the block of code where the variable is used, and the compiler isn't sophisticated enough to prove that in all cases the variable is somehow initialized by assignment.
Initializing all variables at the point where they are declared is a good habit because it reduces the potential for unpredictable behavior as a result of uninitialized data. Some argue that certain static tools work less well when uninitialized variables are obliterated with initializations that give them inappropriate values, making bugs harder to find. However, bugs are more repeatable if they are based on initialized data, and the buggy behavior quite probably also portable among platforms, too.
Some languages initialize your locals for you. In Lisp, (let (x) ...) means that in the code block ...
, variable x
has the value NIL
, since there is no initializer. Static analysis of Lisp code can easily trace facts such as that NIL
is being inappropriately passed to a numeric function. In C and related languages, the issues are a bit different, because for type like int
, there is no equivalent of a wrong-type value such as NIL
. So 0
is substituted, which is a valid value and will not simply blow up the computations with a type mismatch. An inappropriate 0
can lead to an algorithmic bug in a calculation. In the case of pointers, however, the null pointer value is a reasonable facsimile of NIL
in that it is a programmer-visible, portable domain value which says "I do not point to any object". When a pointer in fact does not point to anything for the time being, it behooves us to give it this value rather than leave random bits in it which may accidentally point to an unintended object.
Upvotes: 1
Reputation: 215193
Not only is this practice useless; it's harmful. If you just wrote:
SomeType* ptr = NULL;
/* lots of stuff in between */
ptr = SomeMethod(some, params);
and accidentally happened to use ptr
somewhere in the intervening code, the compiler would have no way of informing you about this error. If you wrote:
SomeType* ptr;
/* lots of stuff in between */
ptr = SomeMethod(some, params);
then any use of ptr
before the assignment is UB, and a good compiler or static analysis tool will inform you of this error.
Upvotes: 2
Reputation: 129324
Aside from the very good points of throwing exceptions, which applies to C++, even in C, it's a good idea to initialize all variables. The compiler will nearly always optimise the initialization away when it can determine it's not needed.
Here's a little example of what can happen if you don't.
SomeType* ptr;
ptr = SomeMethod(some, params);
As you can see, that works fine, no problem with ptr
not having a valid value.
Now, someone decides that it's a good idea to add a bit more code:
SomeType* ptr;
int x = someotherfunction;
if (x > 90)
{
ptr = SomeMethod(some, params);
}
Now all of a sudden your ptr
will have some random nonsense content - may be NULL, but quite likely something else. Yes, we all think we will remember to check back to see if our change has affected something else, etc, etc. But if you've been programming for a few years, I'm almost certainly you've had a few cases of "Oops, didn't think about that".
Imagine that the new code where I added "someotherfunction" is 20 or 30 lines instead, and you can clearly see the problem.
Upvotes: 16
Reputation:
It is useless indeed (this is called a "dead assignment"). However, some prefer to initialize pointers to NULL
when declaring, then assigning to it explicitly, separately. Maybe this is just for readability reasons (perhaps some consider it more readable or find it useful to have the variable declared even when e. g. the assignment is commented out for debugging). I'm not sure I'd do it/consider this as practice.
Also note that as such, most compilers will optimize the assignment away automatically.
Upvotes: 2
Reputation: 33511
In the first case, it is good practice to always assign a value when declaring a new value, so you do not end up with unitialised values (kind of protecting you from your own mistakes). However if it is directly after one another it can be seen as useless.
In the second case, it is completely useless.
Upvotes: 3
Reputation: 318
if "SomeMethod" throws an exception your SomeType* will keep pointing to something you don't want it to point to. Hence it is definitely a good practice to set pointer to null if you don't want it to point to the old thing anymore.
Upvotes: 34