C Language – Is Taking Address of Uninitialized Pointer Undefined Behavior?

c++language-lawyerpointersundefined-behavior

N1570 states that this is undefined behavior:

§J.2/1 The value of an object with automatic storage duration is used
while it is indeterminate (6.2.4, 6.7.9, 6.8).

And in this case, our pointer has an indeterminate value:

§6.7.9/10 If an object that has automatic storage duration is not
initialized explicitly, its value is indeterminate. If an object that
has static or thread storage duration is not initialized explicitly,
then:

— if it has pointer type, it is initialized to a null pointer;

I then presume the following test program exhibits undefined behavior:

#include <stdio.h>

int main(void) {
    char * ptr;
    printf("%p", (void*)&ptr);
}

My motivating concern is the strtol function. First, let me quote the parts of N1570 related to the endptr parameter:

§7.22.1.4/5 If the subject sequence has the expected form and the
value of base is zero, the sequence of characters starting with the
first digit is interpreted as an integer constant according to the
rules of 6.4.4.1. […] A pointer to the final string is stored in the
object pointed to by endptr, provided that endptr is not a null
pointer.

§7.22.1.4/7 If the subject sequence is empty or does not have the
expected form, no conversion is performed; the value of nptr is
stored in the object pointed to by endptr, provided that endptr is
not a null pointer.

This implies that endptr needs to be pointing to an object, and also that endptr is at some point dereferenced. For example, this implementation does so:

if (endptr != 0)
    *endptr = (char *)(any ? s - 1 : nptr);

Yet, this highly upvoted answer as well as this man page both show endptr being passed to strtol uninitialized. Is there an exception which makes this not undefined behavior?

Best Answer

The pointer's value and its address are not the same.

void *foo;

That pointer has an undefined value, but the address of foo, i.e. the value of &foo, must be well-determined (since otherwise we can't access it).

At least that's my intuitive understanding, I didn't dig up the standard now, I just think you're mis-reading it.

When talking about code, the two are sometimes confused ("what's the address of that pointer?" can mean "what's the value of that pointer, what address is it pointing to?") but they are really distinct.

Related Question