1

I wondered today about that it is possible to assign an integer 0 to a pointer, i.e. doing the same like assigning NULL. Until today I assumed, this was new with C++. Has this been a feature of C from the beginning or was it relaxed with a more recent language-standard?

  • 1
    Pointers point to memory address. 0 is a valid invalid memory address – smac89 Jan 16 '18 at 19:08
  • "it is possible to assign an integer 0 to a pointer" Yes for _object_ pointers. Uncertain about function pointers - they have some different rules. – chux - Reinstate Monica Jan 16 '18 at 19:09
  • Doesn't the standard say that a literal of `0`, when converted into a pointer, must be converted into the bit pattern that represents a null pointer, whatever its representation on the platform may be? This implies that a function like `malloc` could return you a pointer to address zero, but you couldn't make one yourself with the `0` literal. – Daniel Pryden Jan 16 '18 at 19:11
  • "from the beginning" --> do you mean C89 or pre-standard? (Fairly wild back then) – chux - Reinstate Monica Jan 16 '18 at 19:11
  • 2
    In practice on any modern hardware and OS I know of, the page of memory starting at address 0 is intentionally unmapped in the MMU so that any attempt to dereference a pointer there will always generate a page fault, which will generally get mapped into a fatal error at the OS level. – Daniel Pryden Jan 16 '18 at 19:12
  • 1
    @DanielPryden Minor: Standard does not call `0` a _literal_, but a _constant_ – chux - Reinstate Monica Jan 16 '18 at 19:12
  • https://github.com/gcc-mirror/gcc/blob/master/gcc/ginclude/stddef.h#L405. In C, GCC defines `NULL` as `0` – smac89 Jan 16 '18 at 19:13
  • Reopened because this question clearly asks for history, not definition or clarification of the differences between `NULL` and a zero constant expression. Please do not mark questions as duplicates unless they are actual duplicates. Overlapping subject matter does not make a duplicate. – Eric Postpischil Jan 16 '18 at 19:19
  • 2
    @DanielPryden: Modern OSes mark address 0 unmapped in **user space**. That is not necessarily so in **kernel space**. And C supports “freestanding environments” (special circumstances) as well as “hosted environments” (normal user programs). I know that memory being mapped at zero has been a problem for some kernel code. Address zero is not used for any C object, so it satisfies the rules that a null pointer be distinguishable from a pointer to a valid object, but it means that incorrect dereferencing of a null pointer does not crash, making some bugs hard to find. – Eric Postpischil Jan 16 '18 at 19:26

3 Answers3

8

Per The C Programming Language by Kernighan and Ritchie, 1978, page 192:

However, it is guaranteed that assignment of the constant 0 to a pointer will produce a null pointer distinguishable from a pointer to any object.

I cannot speak to the history before that.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
4

According to the C Standard (6.3.2.3 Pointers)

3 An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.66) 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.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • 1
    Good answer to the main question. Your thoughts on "Has this been a feature of C from the beginning or was it relaxed"? – chux - Reinstate Monica Jan 16 '18 at 19:14
  • 1
    it was not an advertised feature of 'c', at least in early versions. Though it worked in majority of cases. There fore NULL was defined to make it completely portable. – Serge Jan 16 '18 at 19:23
  • 1
    @Serge: What makes you think it was not a feature of early versions of C? How early? It seems to have been in [C 1989](http://port70.net/~nsz/c/c89/c89-draft.html#3.2.2.3) and, per my answer, in K&R 1978. – Eric Postpischil Jan 16 '18 at 19:40
  • @EricPostpischil this was my recollection. As far as i remember there were some platforms where NULL was not defined to be `(void*)0`. – Serge Jan 16 '18 at 21:01
  • 1
    @Serge The definition of `NULL` is not relevant to "is possible to assign an integer 0 to a pointer" `NULL` may differ _numerically_ and/or _type_ from `0` (per your and mine memory) yet both `ptr1 = 0; ptr2 = NULL;` assigned a _null pointer_. The _null pointers_ assigned may have different bit patterns, but they compare equally as pointers. – chux - Reinstate Monica Jan 16 '18 at 22:35
0

In K&R first edition (pre-ANSI), page 97-98 we have some example code with:

#define NULL 0 /* pointer value for error report */

"C guarantees that no pointer that validly points at data will contain zero, so a return value of zero can be used to signal an abnormal event... We write NULL instead of zero, however, to indicate more clearly that this is a special value for a pointer. In general, integers cannot meaningfully be assigned to pointers."

Clearly here 0, and therefore NULL, is not typed as a pointer but an int. It's worth noting that void * was not introduced until edition 2 (ANSI).

cdarke
  • 42,728
  • 8
  • 80
  • 84