Bertie Wheen
Bertie Wheen

Reputation: 1243

Is there any point to temporarily making a pointer NULL?

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

Answers (6)

Kaz
Kaz

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

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

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

Mats Petersson
Mats Petersson

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

user529758
user529758

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

Bart Friederichs
Bart Friederichs

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

sumeet
sumeet

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

Related Questions