1

I included a check for nullptr in a line of C code. The compiler (gcc) complained when using -std=c17 as well as -std=gnu17.

Is there such a thing as nullptr (or equivalent) in modern C standards? (C11, C17)

If not, then why?

FreelanceConsultant
  • 13,167
  • 27
  • 115
  • 225
  • 5
    Yes. It’s `NULL`. – user3840170 Aug 16 '21 at 13:06
  • @user3840170 Does `NULL` in C differ significantly from `nullptr` in C++? I thought that `NULL` was just something which was defined to be or set to be `0`. Maybe I am mistaken about that however? (Whereas you can only assign `nullptr` to a pointer type in C++.) – FreelanceConsultant Aug 16 '21 at 13:08
  • Technically, `NULL` is an integer of value `0` casted to type `void*`, so you cannot normally assign `NULL` to non-pointer variables (I mean, you can, but you would have a type mismatch, and the compiler may or may not complain about that). – Luca Polito Aug 16 '21 at 13:11
  • 3
    [The `NULL` macro](https://en.cppreference.com/w/c/types/NULL) *may* be expanded to the integer literal `0`. *Or* it may be expanded to the pointer `((void *) 0)`. *Or* anything else corresponding to a null-pointer on the specific target platform. It's implementation defined. It is however guaranteed to always be compatible with all pointers. – Some programmer dude Aug 16 '21 at 13:11
  • @Someprogrammerdude "Or anything else corresponding to a null-pointer on the specific target platform."---I think your wording here is vague and overbroad. It must be an integer constant expression with value `0` or the same cast to `void *`. – kopecs Aug 16 '21 at 13:31
  • Not by me, but I was able to find the answer to your question in literally seconds by consulting the Standards document. If you do not have them, [this question](https://stackoverflow.com/questions/81656/where-do-i-find-the-current-c-or-c-standard-documents) shows where they can be found. – Weather Vane Aug 16 '21 at 14:16
  • @WeatherVane The standards documents, and other references, give details of *what*. They do not often give explanations as to *why*. Perhaps I should have included this. I will edit my question so that you will surely be satisfied. – FreelanceConsultant Aug 16 '21 at 14:24
  • As I said, it was not me who was dissatisfied. Sorry I have literally nothing else to do but try to find a helpful reference. – Weather Vane Aug 16 '21 at 15:23

4 Answers4

5

No, C still uses NULL for a null pointer.

C++ needs a dedicated null pointer literal because it has overloading and template type deduction. These features get confused by NULL, which expands to 0 (or something like that) in C++. However, the risk of such confusion in C is small (maybe _Generic can get confused by this), and in addition, C can use (void*)0 for a null pointer, which mitigates this risk even more.

anatolyg
  • 26,506
  • 9
  • 60
  • 134
  • Side note: It is safe to use `NULL` in C code while using `nullptr` in C++ code. Those two languages are different, and you should not try to compile C code with a C++ compiler, and vice versa. Madness lies in the direction where bilingual code is sought. (Only exception are headers for C libraries which can and should be made bilingual using the `extern 'C' {` construct). – cmaster - reinstate monica Aug 16 '21 at 13:26
3

The closest thing to C++'s nullptr is C's NULL. Which may be

  • an integer constant expression with the value ​0​,
  • an integer constant expression with the value 0 cast to the type void*.

A null pointer constant may be converted to any pointer type; such conversion results in the null pointer value of that type.

The formal C17 specifications state that the stddef.h header defines NULL "which expands to an implementation-defined null pointer constant." (7.19) A null pointer constant is defined as follows (6.3.2.3)

  1. An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.) 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.
  2. Conversion of a null pointer to another pointer type yields a null pointer of that type. Any two null pointers shall compare equal.

Note that this makes the following program ambiguous, as NULL could be an integer constant expression (accepted by the function) or of the type void* (not accepted by the function).

#include <stdio.h>

void printInt(int n)
{
    printf("%d\n", n);
}

int main(void)
{
    printInt(NULL);
}

Which is why nullptr was introduced in C++11. For C, having no function overloading or type deduction, this is less of an issue.

Yun
  • 3,056
  • 6
  • 9
  • 28
2

ISO C 23 now has nullptr, as well as the nullptr_t type. The proposal that introduced it has some rationale.

Bruno Haible
  • 1,203
  • 8
  • 8
0

A null pointer in C is a pointer object pointing at "null". You can turn a pointer into a null pointer by assigning it to a null pointer constant. Valid null pointer constants are 0 and (void*)0. The macro NULL is guaranteed to be a null pointer constant.

The internal representation of the pointer then becomes a "null pointer", which could in theory point at an address different from zero on some exotic system. Similarly, NULL could in theory expand to something different from zero in old, pre-standard C.

When creating C++, Bjarne Stroustrup found all of this to be needlessly complex and decided that "NULL is 0" (source: https://www.stroustrup.com/bs_faq2.html#null). Notably C++ was created long before the first standardization of C, so his arguments are less relevant to standard C than they were to pre-standard C.

For more info about null pointers vs NULL in C, see What's the difference between null pointers and NULL?

Lundin
  • 195,001
  • 40
  • 254
  • 396