Is every null pointer constant a null pointer?

Is every null pointer constant a null pointer?

9

From the C17 draft (6.3.2.3 ¶3):

An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.67) If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.

67)The macro NULL is defined in <stddef.h> (and other headers) as a null pointer constant […].

From this, it follows that the following are null pointer constants: 0, 0UL, (void *)0, (void *)0UL, NULL.

It further follows that the following are null pointers: (int *)0, (int *)0UL, (int *)(void *)0, (int *)(void *)0UL, (int *)NULL. Interestingly, none of these are "null pointer constants"; see here.

The following null pointer constants are null pointers (because void * is a pointer type and 0 and 0UL are null pointer constants): (void *)0, (void *)0UL. In this regard, according to the C17 draft (6.2.5 ¶19-20):

The void type comprises an empty set of values; it is an incomplete object type that cannot be completed.
[…]
A pointer type may be derived from a function type or an object type, called the referenced type. […] A pointer type is a complete object type.

void is not a pointer type itself, and it is an incomplete object type. But void * is a pointer type.

But it seems that the following are null pointer constants which are not null pointers (because there is no cast to a pointer type): 0, 0UL, NULL. (To be precise, while the standard only requires that NULL be defined as "a null pointer constant", it would be permissible to define it as a null pointer constant which is also a null pointer. But it seems that the standard doesn’t require NULL to be defined in such a way that it is simultaneously a null pointer.)

Is every null pointer constant a null pointer? (Is NULL really not a null pointer?)

Finally (and somewhat tongue-in-cheek): In case certain null pointer constants are not null pointers, would they technically be a kind of "non-null pointer"? (This wording appears in some places in the standard.) Note that linguistically we have a so-called bracketing paradox; we can read this as "[non-null] pointer" or "non-[null pointer]".

Share
Improve this question

7

  • 4

    I feel like this is the CS equivalent of philosophy majors trying to define "what it means to exist". I'd stand on the side of "the null pointer constants 0, 0L, and NULL are not null pointers", because there is nothing to imply they point to any data until they are casted. There's more of a case for NULL being considered a null pointer than 0 or 0L, NULL as a value implies the capacity to hold data, which is similar to what one would expect of pointers, while 0 and 0L are perfectly valid for initialized variables.

    – Gumpf

    21 hours ago

  • 3

    I do not understand. You state that the following are null pointer constants which are not null pointers and then you follow Is every null pointer constant a null pointer?. You stated the answer.

    – KamilCuk

    21 hours ago

  • @KamilCuk What I state is that "it seems that […]" – that is, I placed the respective statement under the scope of a modal operator (a term from modal logic) to indicate uncertainty. It is very much possible that I misread or missed relevant parts of the standard.

    – Lover of Structure

    21 hours ago

  • 1

    Och, sure. The thing is, void did not exist, so there have been #define NULL 0. So that both NULL (void*)0 and NULL 0 are correct, there is this "null pointer constant is an integer or pointer". Something not mentioned is that it is constant expressions with the value 0, think about 1-1 1*0 etc. Also see open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf page 144 . Also if one does not know stackoverflow.com/questions/49615338/…

    – KamilCuk

    21 hours ago

  • Linguistically, I personally always read hyphenation as "binding tighter" than spaces. So "non-null pointer" always looks to me to be saying "a pointer that is non-null", rather "a thing that is not a null pointer". I acknowledge this isn't universally adhered to, but I would always find another way to phrase it if I wanted the "thing that is not a null pointer" meaning, especially in technical writing.

    – Ben

    8 hours ago

4 Answers
4

Reset to default

Highest score (default)

Trending (recent votes count more)

Date modified (newest first)

Date created (oldest first)

12

Is every null pointer constant a null pointer?

TL;DR: no.

As you have already observed, integer constant expressions with value 0 are null pointer constants, despite not having pointer type. You have also quoted the specification’s definition of null pointer: "a null pointer constant [] converted to pointer type". That means that null pointer constants of this general form …

(void *)(<integer constant expression with value 0>)

… satisfy the definition of "null pointer". The integer constant expression is a null pointer constant itself, so the cast makes the overall expression a null pointer (in addition to being a null pointer constant).

On the other hand, null pointer constants that take the form of integer constant expressions with value 0 do not satisfy the definition of "null pointer", and there is no other provision in the language spec that would make them null pointers. Examples: 0, 0x00UL, 1 + 2 + 3 - 6.

it seems that the standard doesn’t require NULL to be defined in such a way that it is simultaneously a null pointer.

Correct.

Is every null pointer constant a null pointer?

Definitely not (see above), but for most purposes, it does not matter.

(Is NULL really not a null pointer?)

It depends on your C implementation. The language spec allows either answer. In practice, it is a null pointer in most implementations you’re likely to meet.

In case certain null pointer constants are not null pointers, would they technically be a kind of "non-null pointer"?

No. Null pointer constants that are not null pointers are not pointers at all. They are integers.

Share
Improve this answer

5

Is every null pointer constant a null pointer?

No, and the reason why is in the text you quoted:

If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.

A null pointer constant is not automatically a pointer, just like any integer constant is not automatically a pointer. The constant value must be converted to a pointer type to produce a null pointer.

The resulting null pointer does not have to be zero-valued. It only has to be a value that cannot be the address of any object or function. That value may be 0x00000000 (and on the implementations I’m familiar with it is), or it may be 0xFFFFFFFF, or it may be 0xDEADBEEF, or it may be something else.

Share
Improve this answer

1

  • Most modern architectures do encourage null pointers to be zero valued, such that a type-agnostic zero-filled buffer reinterpreted as a pointer (or structure containing a pointer field) will be a valid null pointer. The language does permit other values (in which case code can get in trouble if it omits constructors or otherwise plays too loose with the rules, if it ever finds itself on one of these architectures). Even in modern times there are some good reasons why an architecture might choose a non-zero null pointer underlying value, though, even though it's a bit more work.

    – Miral

    7 hours ago

4

The null pointer constant may be a void * or some integer type.

Test on your machine:

#include <stdio.h>
#include <stdlib.h>

#define NULL_TEST(n) _Generic((n), 
  void *: "void *", 
  int: "int", 
  long: "long", 
  default: "something else" 
)

int main(void) {
  printf("%sn", NULL_TEST(NULL));
  printf("%sn", NULL_TEST((void*)0));
  printf("%sn", NULL_TEST(0));
  printf("%sn", NULL_TEST(0L));
}

On my machine, I had the below output. Your output may vary for the first line.

void *
void *
int
long

Share
Improve this answer

0

Another fun one is that '' has type int (6.4.4.3(10)) and “The numerical value of the octal integer so formed specifies the value of the desired character or wide character” ((5)), and the same holds of a hexadecimal escape. So both '' and 'x0' are null pointer constants as well. In addition, “floating operands that are the immediate operands of casts” (which must be casts of an arithmetic type to an integral type) are among the legal “integer constant expressions,” so (int)0.0 is a null pointer constant. So could be enum values, the results of sizeof and _Alignof, and the results of an operator whose operands are integral types, for example X^X smf !1.

Several modern compilers define NULL to be a special keyword, such as __null in gcc, or nullptr if cross-compiled on C++. This lets the compiler catch an error if a program uses NULL where an integral constant or void* might implicitly be converted to an expression that is not a pointer, such as a boolean.

Share
Improve this answer

Your Answer

Draft saved
Draft discarded

Post as a guest

Required, but never shown


By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged

or ask your own question.

Leave a Reply

Your email address will not be published. Required fields are marked *