tags:

views:

1142

answers:

7
+2  Q: 

C++ nil vs NULL

OK, I have some C++ code in a header that is declared like this:

void StreamOut(FxStream *stream,const FxChar *name = nil);

and I get: error:

'nil' was not declared in this scope

nil is a pascal thing, correct?

Should I be using NULL?

I thought they were both the same or at least Zero, no?

+3  A: 

Yes. It's NULL in C and C++, while it's nil in Objective-C.

Each language has its own identifier for no object. In C the standard library, NULL is a typedef of ((void *)0). In C++ the standard library, NULL is a typedef of 0 or 0L.

However IMHO, you should never use 0 in place of NULL, as it helps the readability of the code, just like having constant variables in your code: without using NULL, the value 0 is used for null pointers as well as base index value in loops as well as counts/sizes for empty lists, it makes it harder to know which one is which. Also, it's easier to grep for and such.

notnoop
Never use 0 as NULL?
GMan
Never use 0. Why?
AndreyT
@GMan, @AndreyT, just clarified the post.
notnoop
I think that was the wording you were looking for.
GMan
IMO - 0 is an integer value, NULL implies a pointer. Using 0 makes me suspect the programmer forgot what they were doing or were just sloppy. Also **sizeof(NULL)** should be the same as **sizeof(void*)**.
NVRAM
Not in C++, which is what the question is about. In C++, NULL is an *integer*, not a pointer. `sizeof(NULL) == sizeof(int)`. I've always had this sneaking suspicion that Stroustrup did this deliberately, because he never liked NULL and wanted to make its use in C++ easier to argue against than it is in C ;-)
Steve Jessop
@NVRAM: "Should be"? Maybe. But neither in c, nor in C++ `sizeof(NULL)` is guaranteed to be the same as `sizeof(void *)`.
AndreyT
@onebyone: NULL is an *integer* in C++, but not necessarily specifically `int`. `NULL` can be defined as `OL`, which would mean that `sizeof(NULL) == sizeof(long)` in that case.
AndreyT
@AndreyT: While I agree and prefer 0 to NULL in C++, in C null is defined as `((void*)0)`, and as such as far as C is concerned `sizeof(NULL)` is guaranteed to be `sizeof(void*)`.
David Rodríguez - dribeas
@AndreyT: oops, silly error. You've jogged my memory that `0L` is actually one of the examples in the footnote in the standard, isn't it? Thanks for the correction.
Steve Jessop
@dribeas: In C `NULL` can be defined as `(void *) 0`, but it doesn't have to be defined that way. In C `NULL` can be defined as plain `0` as well. Actually, `NULL` in C can even be defined as `'\0'`. So, no `sizeof(NULL)` is *not* guaranteed to be the same as `sizeof(void *)` in C.
AndreyT
@dribeas: in C99 at least, 7.17 says that NULL is "an implementation defined null pointer constant". 6.3.2.3 says "an integer constant expression with the value 0, or such an expression cast to type `void *`, is called a null pointer constant". So `#define NULL 0` is permitted in C (although not the usual way of doing it), and NULL is *not* required in C to be `((void*)0)`.
Steve Jessop
It only really matters in functions that take variable numbers of parameters. `printf("%s%d", 0, 0, 123)` might print `(null)0` and it might print `(null)123` depending on whether `sizeof(char*) == sizeof(0)`.
jmucchiello
+10  A: 

In C++ you need to use NULL, 0, or in some brand new compilers nullptr. The use of NULL vs. 0 can be a bit of a debate in some circles but IMHO, NULL is the more popular use over 0.

JaredPar
To clarify for others `#DEFINE NULL 0` and `null_ptr != NULL` null_ptr is used only to signify a pointer with no value, 0 is a valid pointer value but barring embedded systems it's probably an invalid one.
joshperry
It's `nullptr` - channel9 has some nice video about it: http://channel9.msdn.com/shows/Going+Deep/Stephan-T-Lavavej-Everything-you-ever-wanted-to-know-about-nullptr/
Johannes Schaub - litb
@joshperry, sorry but you have not clarified, but confused it. `0` is not a pointer value, but it's an integer value - not barring any system. It can be converted to a pointer value. See http://stackoverflow.com/questions/423823/whats-your-favorite-programmer-ignorance-pet-peeve/1331729#1331729
Johannes Schaub - litb
A `0` in a pointer context **is** a null pointer, by definition. http://c-faq.com/null/index.html
Carl Norum
@Carl Norum, you are using a different definition of "is". You are saying "A is B" iff "A can be converted to be B". That definition makes sense when passing arguments to functions. But to most people (or so would i assume, at least), `is` means "is one and the same" when taken out of context. So these people then think `0` is both an integer and a pointer, and would think if you do `ptr + 0` (surely this is a "pointer context") you could add a pointer and a null pointer, etc... It's only best to keep it clear and say "0 is converted to a null pointer when needed", instead.
Johannes Schaub - litb
In fact, i believe it's this "0 is a null pointer in some contexts" that made some people believe that "0" may not be portable as a "null pointer" on some embedded systems. If instead one says "0 is converted to a null pointer in some contexts", no such suspicions can come up.
Johannes Schaub - litb
@Carl, BTW the C-Faq you link to says exactly that, not what you said: *According to the language definition, an "integral constant expression with the value 0" in a pointer context is converted into a null pointer*
Johannes Schaub - litb
I can't be bothered to fetch the C++ standard from upstairs, but I looked this up in C99 earlier, and it's worth bearing in mind that for C at least, a "null pointer" and a "null pointer constant" are not the same thing. In C terms 0 is a null pointer constant, and NULL is a null pointer constant, and `(void*)0` is both a null pointer and a null pointer constant, and NULL may or may not be a null pointer, but 0 is certainly not a null pointer. In C++, both 0 and NULL are integers, not null pointers, but they might be null pointer constants if C++ uses that terminology.
Steve Jessop
It's basically the same argument that says "arrays are pointers". They aren't, but they silently convert to them when you're not looking.
Steve Jessop
+4  A: 

nil does not exist in standard C++. Use NULL instead.

Marcin
C++ doesn't have null in all lower case
JaredPar
type-o corrected
Marcin
+1  A: 

0 is the recommended and common style for C++

Guido
Recommended by whom?
NVRAM
Recommended by Stroustrup: http://www2.research.att.com/~bs/bs_faq2.html#null
Steve Jessop
It is not "recommended" by Stroustrup. It is more like "personally preferred" by Stroustrup.
AndreyT
I would not even say using 0 is common. I have seen code with it in but common is stretching it. NULL is common though.
Martin York
"If you have to name the null pointer, call it nullptr" sounds to me like a recommendation not to use NULL (granted, a null pointer is not the same thing at all as a null pointer constant, but I think it's clear he's talking about what literal should be used to generate null pointers). In fact it's a direct order, but given that he's not the boss of me I choose to interpret it as advice ;-)
Steve Jessop
+1 Guido. I prefer 0. A programmer has bigger problems if they do not understand the argument they are evaluating or what NULL represents (which varies). It's a pointer comparison, it doesn't need to be candy-coated or made more complicated. If I want a labeled (unambiguous) type, I'll make a descriptive constant for it.
Justin
+1  A: 

just add at the beginning

#define null '\0'

or whatever you want instead of null and stick with what you prefer. The null concept in C++ is just related to a pointer pointing to nothing (0x0)..

Mind that every compiler may have its own definition of null, nil, NULL, whatever.. but in the end it is still 0.

Probably in the source you are looking at there is a

#define nil '\0'

somewhere in a header file..

Jack
You've defined a **char** constant, useful for handling null-terminated strings. The OP code expects **nil** to be a pointer.
NVRAM
Actually I always used it in my "common.h" header file and compiler never complained, execution neither. But maybe with -Wall it will say something about that..
Jack
Actually, defining `NULL` as `\0` is a perfectly valid thing to do in C and C++. I would be quite surprised to see an implementation that does this, but nevertheless `\0` is a valid way to define `NULL`.
AndreyT
Proof for C++ in 2.13.2/4, which says "The escape `\ooo` ... [is] taken to specify the value of the desired character". So `\0` has value zero and is a valid value for NULL. I'm not sure about `false` for C++ though: Its value is ... `false` and not zero, and to become zero, you need a promotion to int or conversion to another integer type. But this would require both an integer and a pointer conversion - so it would become illegal. But nontheless, i've tried various implementations, and they all accept `false`
Johannes Schaub - litb
A: 

I saw some comments on why not to use 0. Generally people don't like magic numbers, or numbers with meaning behind them. Give them a name. I would rather see ANSWER_TO_THE_ULTIMATE_QUESTION over 42 in code.

As for nil, I know Obj-C using nil as well. I would hate to think that someone went against the very popular convention (or at least what I remember) of NULL, which I thought was in a standard library header somewhere. I haven't done C++ in awhile though.

Sean Copenhaver
Personally, I think 0 is so incredibly magic that it's pointless to pretend you mean some special kind of 0. Sure, you can say INTEGER_THAT_CONVERTS_TO_NULL_POINTER (which is what NULL is), or you can say DEFAULT_INITIAL_VALUE_OF_A_GLOBAL_INT_VARIABLE, or INDEX_OF_FIRST_OBJECT_IN_AN_ARRAY. But everyone knows you mean 0, and translates to 0 in their heads. I used to carefully use NULL, and I don't object to it, but I tend just to stick with 0. Same goes for `'\0'`, although I rate a ASCII_NUL macro as being at least as useful as NULL.
Steve Jessop
A: 

If you run a search through glibc you'll find this line of code:

#define NULL 0

It's just a standard way (not sure if it was published anywhere) of marking empty pointers. Variable value of 0 is still a value. Pointer pointing to 0 (0x0000... (it's decimal zero)) is actually pointing nowhere. It's just for readability.

int *var1, var2;
var1 = 0;
var2 = 0;

The above two assignments are not the same though they both look the same