Pointers
Overview
Pointers have the same size as the machine's word size since they should be able to refer to any virtual address. All pointers are either valid, null, or indeterminate.
A null pointer constant is an ICE with value 0, an ICE with value 0 cast to type void*, or the nullptr value.
C allows arithmetic on pointers, where the computed value is scaled according to the size of the data type referenced by the pointer. All pointer differences have type ptrdiff_t, provided by the <stddef.h> header.
nullptr
The nullptr keyword is introduced in C23. Its type, nullptr_t, is provided in <stddef.h>. Objects of this type have the same size and alignment as a pointer to a character type. The corresponding object representation is the same as that of a null pointer value of type void*.
A value of nullptr always compares equal to any null pointer constant.
NULL
The NULL macro is defined to be some null pointer constant. As a result, a conforming compiler can choose any of the following to expand it to: 0U, 0, \0, 0UL, (void*)0, an enum constant of value 0, etc.
As a result, it's usage is not predictable. In particular, make note that it doesn't have to be a pointer constant.
Aliasing
An object shall have its stored value accessed only by an lvalue expression with one of the following types:
- A type nearly compatible with the effective type of the object.
- A type that is the signed or unsigned type corresponding to the effective type of the object.
- A type that is the signed or unsigned type corresponding to a qualified version of the effective type of the object.
- An aggregate or union type that includes one of the aforementioned types among its members.
- A character type.
Strict Aliasing Rule
The strict aliasing rule dictates that pointers are assumed not to alias if they point to fundamentally different types, except for character pointer types and void *. The rule is leveraged by the compiler for optimization opportunities.