5 ms·
nullptr, I believe, is compatible with C interfaces (as is simply passing 0) while not suffering from the issues described here.
by Coding_Cat 10y ago
nullptr, I believe, is compatible with C interfaces (as is simply passing 0) while not suffering from the issues described here.
- i336_ 10y agoWhat are the semantic/grammatical/"magical" differences between 0 and NULL? 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.
- mhogomchungu 10y agosizeof(NULL) in 4 in C++ in a 64 bit system. 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.
- AbacusAvenger 10y agoThat's not true. sizeof(NULL) is the same in C++ and C: https://goo.gl/WL1akj https://goo.gl/WL1akj
- mhogomchungu 10y agoI looked up at my g++ compiler and i found this: http://pastebin.com/VpSsEkBY http://pastebin.com/VpSsEkBY 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/d0d7f784833bbb0b2d279310ddc6afb52fe47a46/mingw-w64-headers/crt/stddef.h https://github.com/Alexpux/mingw-w64/blob/d0d7f784833bbb0b2d...
- fnj 10y agoWhat file are we supposed to be looking at?
- fnj 10y agoI looked into this. #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.
- ben0x539 10y agofwiw, in C++11 onwards, apparently NULL is allowed to be nullptr and not an integral constant.
- CJefferson 10y agoNo, that's wrong! 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).
- fnj 10y agoThat would be pretty surprising if true, but it's not: #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~"
- CJefferson 10y agoApologises, I mis-remembered the rule -- it is only C++ types which have a non-trivial destructor which cause an abort when you pass them to a variadic funciton. 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.
- palunon 10y ago>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 ?
- CJefferson 10y agoNo, but once you start invoking undefined behaviour, all bets are off. 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"); }