xdevel2000
xdevel2000

Reputation: 21364

C23 and memory representation of nullptr

I'm reading the C document n3042 Introduce the nullptr constant

and when it enumerates the properties of nullptr there is the following:

so if I write the following code is it reliable to verify what the previous property asserts?

void* null_ptr1 = NULL;    
void* null_ptr2 = nullptr;   

if (memcmp(&null_ptr1, &null_ptr2, sizeof(void*)) == 0) 
    printf("binary rep. of NULL and nullptr is the same.\n");
else 
    printf("binary rep. of NULL and nullptr is not the same.\n");

Upvotes: 1

Views: 110

Answers (2)

Eric Postpischil
Eric Postpischil

Reputation: 222292

The actual language in the standard, in C 2024 7.21.3, is:

An object representation of the value nullptr is the same as the object representation of a null pointer value of type void *.

Since a null pointer value might have multiple object representations, we cannot be sure that a nullptr representation will necessarily be the same as any void * null pointer representation. However, we can be sure that if we reinterpret the bytes of a nullptr as void *, that will produce a null pointer value. So this code prints “False” since a null pointer evaluates as false:

puts((union { nullptr_t n; void *v; }) { nullptr } .v ? "True" : "False");

Upvotes: 4

John Bollinger
John Bollinger

Reputation: 180058

so if I write the following code is it reliable to verify what the previous property asserts?

The C language spec does not forbid there being multiple distinct null pointer representations for any given pointer type. If there is more than one, then it does not specify which NULL and nullptr correspond to, or even that either one of them always corresponds to the same one. Therefore, as far as the spec is concerned, your program might print "binary rep. of NULL and nullptr is not the same."

Additionally, as @PaulHankin described in comments, your program is not even testing what you seem to intend for it to test. If you want to examine the (a) representation of nullptr then you need to look at an object of type nullptr_t. Converting nullptr to type void * by assignment produces a null pointer of type void *, but there is no guarantee that this preserves representation if there is more than one option for representation. Your test would be more appropriately written as:

static_assert(sizeof(void *) == sizeof(nullptr_t));
void* null_ptr1 = NULL;    
nullptr_t null_ptr2 = nullptr;

if (memcmp(&null_ptr1, &null_ptr2, sizeof(void*)) == 0) 
    printf("binary rep. of NULL and nullptr is the same.\n");
else 
    printf("binary rep. of NULL and nullptr is not the same.\n");

I think it's pretty unlikely that you would observe a difference in practice, even on an implementation that did have multiple null pointer representations for type void *, but the spec does not guarantee that you won't.

Upvotes: 3

Related Questions