tags:

views:

265

answers:

5

I'm confused why the following C++ code can compile. Why does a call to delete the method of 0 not produce any error?!

volatile *arr = NULL;     // or if i use 0, it's the same thing      
delete arr;

I did try to run it, and it did not give me any error at all...

A: 

NULL and 0 aren't the same thing. In C++ you should use 0.

There is nothing syntactically wrong or ambiguous about deleting the null pointer. In fact, this is by definition a no-op; that is, the operation of deleting the 0th address is equivalent to doing nothing at all.

wilhelmtell
Actually, in C++, NULL is defined to be 0. Moreover, NULL vs. 0 is a stylistic debate for which there is no clear-cut answer.
rlbond
There's absolutely no reason to prefer 0 over NULL in C++. Although, for some reason, the recommendation to "use 0 in C++" pops up here and there from time to time. I don't know where this urban legend originates from, but, once again, there's absolutely nothing wrong with using NULL in C++ and generally, for the sake of readability, NULL is preferrable over 0.
AndreyT
Stroustrup prefers 0 instead of NULL: http://www.research.att.com/~bs/bs_faq2.html#null
ChrisW
It seems to me that NULL is better style, if only because when you are looking for pointer issues you can search for it. In a program that uses 0 instead of NULL, searching for 0 will get you both pointer and integer uses of 0, and the irrelevant extra results will take longer to scan through.
Jeremy Friesner
The answer is neither: `nullptr`. Since there is no `nullptr` yet, you can create this type and settle the issue. That said, I find `NULL` ugly. It's all-caps (ugly), obtrusive (ugly), and ick.
GMan
Stroustrup's preference is based on his dislike of macros in general. Also, it originates in those dark ages when C and C++ header files were often mixed up and the C-only definition of NULL as '(void *) 0' (completely unsuitable for C++) would leak into the C++ code. These time are long over and, once again, there's nothing wrong with NULL in C++ code.
AndreyT
Except that it looks bulky and ugly :)
GMan
@GMan - what's wrong with capitalized constants?
Tom
I always felt the only thing that should be all-caps is macros, like `DO_SOMETHING_WITH_IT(x)`. Constants are not macros, they are: `static const int ThisIsANumber = 123;`. You don't type all caps with variable names, do you? I find upper-camel case is a nice in-between. Similarly, everything in the C++ language is lower-case and it's much easier to read if everything is uniform, `nullptr` will be all-lower so why use a replacement that's all-upper? when NULL and 0 are shunned and nullptr is in place, getting used to all-caps is heartache waiting to happen.
GMan
A: 

Although your example is trivial, there is no way for a compiler to know (at compile time) the value of a pointer.

You can also dereference null at compile time:

// this code compiles
Object* pObject = 0;
pObject->SomeMethod();

Compilers aren't built to handle these kinds of error conditions at compile time.

And most (all?) implementations have 'delete 0' as a non-operation. This code should run fine:

Object* pObject = new Object();
delete pObject;
pObject = 0;
delete pObject;

Although I'm not 100% sure on that :)

Josh
I don't think deleting null is a run-time error.
Jacob
You're right.I have run into double-deletion issues though... or maybe I'm imagining things?
Josh
Any C++ compiler that treats "delete NULL" as anything other than a no-op is a buggy compiler. The C++ language specifies that deleting a NULL pointer is safe to do. (Calling delete twice on the same non-NULL pointer, on the other hand, will get you into trouble)
Jeremy Friesner
@Jeremy Friesner: I get your point, but from the pedantic point of view, 'delete NULL' is ill-formed. 'NULL' in C++ is required to stand for an integral zero, and 'delete' cannot be applied to integral 0. 'delete NULL' is as ill-formed as 'delete 0', i.e. very :)
AndreyT
... 'delete (int *) NULL' on the other hand is legal and is indeed required to be a no-op.
AndreyT
+11  A: 

The C++ language guarantees that delete p will do nothing if p is equal to NULL.

For more info, check out Section 16.8,9 here:

Jacob
Still, the question was why does the code *compile*; not why isn't there a run-time error.
Josh
It is legal in C++ to delete a NULL pointer, therefore the compiler is ok with it.
Jim Buck
It it legal to dereference null too? How about overflowing the stack? Show me a compiler that errors out on those conditions...
Josh
As far as the compiler is concerned, all of those things are legal. The run-time may have a different opinion, of course...
Jeremy Friesner
Wow, Josh, maybe I'm just reading wrong but you sound pretty defensive or something. Deleting null is fine, it does nothing.
GMan
@Josh: The compiler is not supposed to detect every error. It is impossible. The compiler is only required to detect so called "constraint violations", which are explicitly described in the language specification. Detecting all other errors is your problem, not compiler's. Dereferencing null pointer is illegal, but it is not a constaint violation, which means that the compiler is not required to worry about it. There's simple no way compiler can detect it in general case.
AndreyT
Gman - fair point. AndreyT - that's exactly my point! I read the question differently to you guys. I read it as: "Why doesn't the compiler pick up this kind of thing?". You guys read it as "Why isn't delete "null" illegal?".I was trying to explain the difference between a run-time exception and a compiler error, but failed?
Josh
@Josh it looks like we read the question one way (the way it was written) and you read it another way (the way it was not written). The question clearly asks why delete NULL doesn't cause a compile error. The answer is because it is legal, well defined, perfectly fine.
Daniel Daranas
+1  A: 

You can delete a NULL pointer without problem, and the error you may/can have won't be at compilation time but at runtime.

int *ptr_A = &a;
ptr_A = NULL;
delete ptr_A;

Usually it's convenient to do :

...
delete ptr;
ptr = NULL;
Vincent Briard
It's usually bad practice to NULL a pointer. The reason is that pointers should be encapsulated in classes. `delete` then occurs in destructors, after which the pointer doesn't even exist anymore or in assignment, in which the pointer gets a new value. Hence, there are usually no methods that would set the pointer to NULL. The one obvious exception is an "optional" part of an object that's no longer needed, but consider `boost::optional<T>` for that.
MSalters
A: 

It is a de-facto standard in C and C++ languages (and not only in them) that resource deallocation routines must accept null-pointer arguments and simply do nothing. Actually, it is a rather convenent convention. So, the real question here: why does it surprize you? What makes you think that it should produce an error? Moreover, what makes you think that it should fail to compile???

BTW, your question, the way it is stated, doesn't seem to make much sense, since your code actually cannot compile. The supposed pointer declaration lacks a type, which will make any compiler to issue a diagnostic message.

AndreyT
s/de-facto/de jure/ - see quote from ISO standard.
MSalters