Does (size_t)((char *)0) ever not evaluate to 0?
According to the responses in "Why subtract null pointer in offsetof()?" (and my reading of K&R), the C standard doesn't require that (size_t)((char *)0) == 0
. Still, I've never seen a situation where cast开发者_开发百科ing a null pointer to an integer type evaluates to anything else.
If there is a compiler or scenario where (size_t)((char *)0) != 0
, what is it?
Well, as you know, the physical representation of null pointer of a given type is not necessarily all-zero bit pattern. When you forcefully convert a pointer (any pointer) value to integer type, the result is implementation defined, but normally (and that's the intent) the numerical value of the pointer - the numerical address - remains unchanged, if possible. This means that if on a given platform a null pointer of type char *
is represented by 0xBAADF00D
pattern (for example), the above expression will evaluate to 0xBAADF00D
, and not to zero. Of course, for that you'd need a platform with non-zero null-pointers. I personally never worked with such platforms, although I heard about a number of real platforms like that out there (like, in the realm of embedded platforms it is not something unusual).
Moreover, as an additional note, null pointer values of different types can have different physical representations, meaning that in theory you can get different values from (size_t) ((int *) 0)
, (size_t) ((char *) 0)
and (size_t) ((double *) 0)
. But that would be a rather exotic situation, albeit perfectly possible from the point of view of abstract C language.
P.S. Read here (C FAQ) for some examples of actual platforms with non-zero null pointers.
The only thing that the C standard requires of a null pointer's runtime representation is (6.3.2.3/3 "Pointers"):
...the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function. Conversion of a null pointer to another pointer type yields a null pointer of that type.
Any two null pointers shall compare equal.
Your question is an interesting one, though. Personally, I'm unaware of a platform that doesn't use the runtime value 0 to represent a null pointer. However, the standard doesn't require it, so if you can avoid the assumption in your code, why not?
I'd also be interested in anyone who knows of a system that uses a non-zero runtime value for a null pointer.
The C99 standard says that when you convert an integer value 0
to a pointer, it becomes a NULL pointer. So ((char*)0)
is a NULL pointer. A NULL pointer need not have an actual binary representation of 0
. It can be, for example 0x12345678
.
The C standard further states that when you convert a NULL pointer to an integer constant, the result is "implementation-defined". In reality, what compilers do is simply cast the use the numerical value of the pointer to the corresponding integer value, as AndreyT said. So in the example above, the integer value might end up being 0x12345678
, though technically it could be anything at all (ie. the compiler is allowed to say "converting a NULL pointer back to an integer value results in value 0xDEADBEEF
"). Note that this means that even on platforms where the NULL pointer has the value 0
, the compiler is allowed to convert it to an arbitrary integer value upon conversion. In reality, however, no compilers do that because it would be fairly insane.
So, yes, the C standard allows a lot of things. In reality, any platform you are likely to work on will represent a NULL pointer as 0
and converting a NULL pointer to an integer value will result in 0
. Look here (section 1.14) for a list of some exceptions of (obscure) architectures which do not use 0
for a NULL pointer.
This doesn't apply to char*
or even C, but a smart pointer class which indexes into an array might choose to represent NULL
as -1
because 0
is a valid array index.
Considering the idiom of memset( my_new_struct, 0, sizeof my_new_struct );
, even a debugging-centric system is unlikely to break that identity.
精彩评论