I understand their similarity in terms of NULL's equivalence to memory address 0 and boolean false, but I'm increasingly aware that there's some hidden behavior.
Does NULL strictly resolve to '(void * )0', or can it be influenced by anything else?
Also, does it behave differently in C vs. C++? I suspect it might.
EDIT: Someone else just replied close to this thread chain just said it's defined in C++ as 0 without '(void * )'. If anyone can expand on this that would be awesome.
sizeof(NULL) is 8 in C in a 64 bit system.
The difference is because NULL in C is a variable of a void pointer type with a value zero. In C++,NULL is a variable with a value zero that gets deduced to an int type.
That g++ compiler is using a gnu extension through the __GNUG__ code path. The "true" C++ code path is at line 11.
Edit:
Answering the person below,the file that defines NULL is "stddef.h"
An example of the file online that defines NULL is here: https://github.com/Alexpux/mingw-w64/blob/d0d7f784833bbb0b2d...
#include <iostream>
int main() { std::cout << "sizeof(NULL) = " << sizeof(NULL) << '\n'; }
Compiling with both g++ 6.2.1 and clang++ 3.9.1 with -std=c++11 in both cases gives: sizeof(NULL) = 8
AFAICT, NULL should not even be defined at all in C++ 11; certainly if you include neither <stddef.h> nor <stdlib.h> nor <cstddef> nor <cstdlib>.
I could never get it to compile on x86_64 linux without saying 8.
Bottom line: NULL works in the execlp call, whether from C or from C++. nullptr would be cleaner.
You can't pass nullptr to a variadic function. It causes a run-time call to abort. You can pass 0, or NULL (which is just a macro defined to 0).
#include <unistd.h>
int main() { execlp("ls", "ls", nullptr); }
g++ -std=c++11 -o x x.cpp
"cpp cpp.cpp cpp.cpp~ cryptkeeper q q.c q.c~ q.cpp q.cpp~ x x.cpp x.cpp~"
HOWEVER. This is still undefined behaviour. nullptr is an object of type std::nullptr_t. When you pass it to execlp, it just gets pushed through as a bit-pattern (as with any type passed to a variadic C function), and there is no guarantee what comes out looks like a "true" (void*)0 C-style null pointer.
EDIT: On further inspection, both g++ and clang++ on mac (and I'd guess on linux) choose to pass 'nullptr' to variadic functions as an 8-byte all-0 value. That makes sense -- it makes it easier to implement nullptr I guess if you treat it as a null pointer! But, that's not required behaviour by the standard, I could make nullptr internally be any mess of values I like.
But compiler writers usually aren't trying to go out of their way to trip you up.
Can you provide an example of a compiler where nullptr doesn't have a 0 bit pattern ?
For example, there are compilers that print nothing for the following function, with uninitialised 'i', whereas some programmers assume that i must take "some value", so one of A and B will be printed.
int func() {
int i;
if(i > 0) printf("A");
if(i <= 0) printf("B");
}No, it doesn't. It goes through a proper conversion to a pointer.
> [passing nullptr and getting 0 out of va_arg is] not required behaviour by the standard
Yes, it is. See C++11 and C++14 standards, section 5.2.2 paragraph 7.
You've been all over this thread shouting at people about how wrong they were, and even in your correction you are still mistaken. Please try to refrain from that in the future; lots of people reading these threads are going to be very confused about what is technically correct here, and I'm not willing to go reply to all of them.
Perhaps some edits and/or deletes are appropriate?
Ycombinator allows neither edits or deletions after a short amount of time it seems.
I guess the lesson is: don't yell at people if you aren't up-to-date on what you are yelling about :)
In my defence, I thought I was up to date. I did know all about how C++ and varargs interact, I was just unaware there was a specific addition to varargs just for nullptr, and I'll be honest it didn't even occur to me to check!
While I agree it's a sensible feature, it's also (for me) been the final straw on giving up on understanding C++ (not using, but understanding...)