4 ms·
The two things referred to by the terms ”NUL byte” and ”null pointer” (aka ”NULL”) are quite distinct and mixing them up is not advisable, but calling the NUL b
by Sharlin 7y ago
The two things referred to by the terms ”NUL byte” and ”null pointer” (aka ”NULL”) are quite distinct and mixing them up is not advisable, but calling the NUL byte a NULL byte, where it’s clear from the context what is meant, is not that confusing.
- thaumasiotes 7y agoIn the context of C, where NUL characters are most likely to be discussed, "NUL byte" and "null pointer" refer to exactly the same thing, that thing being the integer value 0.
- AnimalMuppet 7y agoOnly if pointers are 8 bits. More specifically, "NUL byte" is the character that has value 0, whereas "null pointer" is the pointer that has value 0. OK, I'll try to stop being the pedant. I'll let the real pedants poke holes in what I said...
- thaumasiotes 7y ago> More specifically, "NUL byte" is the character that has value 0, whereas "null pointer" is the pointer that has value 0. Where is this enforced? You can assign between notional types without a problem. Whatever the context, providing 0 will have the same effect no matter how you labeled it.
- AnimalMuppet 7y agoEnforced? Not, as I think you're pointing out, by prohibiting conversion. That is, if char c = '\0'; void* p = (void*)0; int a = (int)c; int b = (int)p; then a == b resolves to true. In that sense, they are the same - which I believe is your point. In that point, you are completely correct. The difference is that I can't do *c In that sense, they are not the same - not in the sense of numberic value, but in the sense of type. Also, c is 8 bits, and p (at least these days) is 32 or 64. (I pity anyone who ever had to work in an environment where p was 8 bits!) So they are the same numerically, but they are different both in type and in memory footprint.
- thaumasiotes 7y agoa == p will also resolve to true. So will c == p. a and b don't add anything to your example; they're just in there to make c and p look like they're more different than they are. $ cat zero.c #include "stdio.h" int main(int argc, char* argv[]) { char nul = 0; void* null = 0; if( nul == null ) { printf("compared char to pointer; they are the same\n"); } else { printf("found a difference between char and pointer\n"); } return 0; } $ gcc -o zero zero.c zero.c: In function ‘main’: zero.c:7:10: warning: comparison between pointer and integer if( nul == null ) { ^~ $ ./zero compared char to pointer; they are the same $ You get a warning, but not an error, for making the comparison. By contrast, assigning the integer zero to a void* isn't even a warning -- it's just a natural thing to do. There isn't another way to set a pointer to NULL. There is another way to set a character to 0, the '\0' syntax, but that's not a warning either. C will think nothing of adding '!' to 'P' and getting 'q'. That's not strange because addition is a pretty normal thing to do with integers. You're right that a char variable should only occupy 8 bits of memory, but that's an implementation artifact, not a theory of what the value '\0' means. That value is unambiguously the integer zero with infinite precision. The reason it only occupies 8 bits is that you can't let it have infinite bits.
- AnimalMuppet 7y agoHmm. Probably true. What about c == p? I don't recall whether both will promote to numeric, or whether it's a type error. For that matter, what does (uncasted) p = c do? How about c = p? [Edit: You updated while I was writing; my first question you already answered. Warning, not error.]
- thaumasiotes 7y ago$ cat pointers.c #include "stdio.h" int main(int argc, char* argv[]) { char Z = 'Z'; char q = 'q'; void* null = 0; printf("Z is \\x%02x\n", Z); printf("But if it were a pointer, it would be %08x\n", Z); printf("Watch this:\n\n"); null = Z; /* %p to print a pointer value */ printf("Our void* is now: %p\n", null); q = null; printf("And q is: %c\n", q); return 0; } $ gcc -o pointers pointers.c pointers.c: In function ‘main’: pointers.c:12:7: warning: assignment makes pointer from integer without a cast [-Wint-conversion] null = Z; ^ pointers.c:17:4: warning: assignment makes integer from pointer without a cast [-Wint-conversion] q = null; ^ $ ./pointers Z is \x5a But if it were a pointer, it would be 0000005a Watch this: Our void* is now: 0x5a And q is: Z $ The assignments are warnings. They work just like you'd expect them to work. Notice all the different printf flags? This is why you need them.
- Sharlin 7y agoThat’s not accurate. NUL byte is a byte with an all-zeros bit pattern, where a null pointer is a special pointer value (and thus pointer-sized) that can be coerced from the integer literal 0, but not in general from an arbitrary integer with value zero, and what’s more, a null pointer value is not guaranteed to have an all-zero bit pattern!