Quentarez said:
I, personally, would not consider this to be UB.
I don't have supreme knowledge of the standard, nor do I have any
references to the standard to support this claim.
I decided to take a different route, and see what the compiler does with a
NULL pointer. I tested it on two compilers: MSVC6 and gcc 3.3.5.
Observing the behavior of any number of implementations doesn't
demonstrate that the behavior is defined. Undefined behavior is
exactly that, undefined. Specifically, it's
behavior, upon use of a nonportable or erroneous program construct
or of erroneous data, for which this International Standard
imposes no requirements
(C99 3.4.3p1)
Even assuming that it's UB, the behaviors of MSVC6 and gcc are
entirely consistent with the standard. (*Any* behavior would be
entirely consistent with the standard.)
The only way to determine whether a given construct invokes undefined
behavior is by a careful reading of the standard.
It has already been shown previous to this post that (void *)0 is indeed a
way to get a NULL pointer, so I will refer to it as a NULL pointer from now
on.
It's better to refer to this as a "null pointer", not a "NULL
pointer". NULL is a macro that expands to a null pointer constant;
using all-caps NULL for anything else is misleading.
From what I've learned, a pointer always points /somewhere/, even if that
somewhere is not where you intended.
Not necessarily. As far as the language is concerned a null pointer
points nowhere. (It might happen to point to some location in
physical or virtual memory, but no program can determine that without
invoking undefined behavior.)
More concretely, on a system with 128 megabytes of virtual memory, a
pointer with the value 0x10000000 (that's 256 megabytes) doesn't point
anywhere -- or maybe it points to a memory card you haven't installed
yet. (For the sake of this example, I'm making several assumptions
about pointers that are commonly true, but are not required by the
standard.)
From simply compiling and running the given code, I get the output 00000000
on MSVC6 and (nil) on gcc.
Using gcc on three different platforms, I get "0x0", "0", and "(nil)".
It's the runtime library, not the compiler, that implements printf.
(As far as the standard is concerned, the compiler and the library are
both part of the implementation; in other words, "gcc" is not a
complete description of the implementation.)
[snip]
Based on my observations, it seems that
printf("%p\n", (void *)0);
is not UB.
Based on your observations, it could very well be UB.