Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a null pointer constant be any integer constant expression evaluated to 0?

The standard says:

"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; see 7.19."

Source: ISO/IEC 9899:2018 (C18), §6.2.3.2/3 "Pointers".

The most common null pointer constants are of course, 0 and (void*) 0 used by most implementations as null pointer constant, but as the standard mandates - "An integer constant expression with the value 0, or such an expression cast to type void*" - a null pointer constant shall also be any of the following:

  1. 1 * 0
  2. 0 * 0
  3. 0 - 0
  4. 25 - 25
  5. (-4) + (4)
  6. (0 * ((0 * 25) * 3)
  7. (0) * (-100)

Like any of their pendants preceded by (void*), f.e. (void*) (1 * 0) or (void*) (25 - 25).

As well as boolean expressions:

  1. (void*) ((1 + 1) == 25)
  2. (void*) !(9)

Thus, any statement like one of these:

  1. int* ptr = 25 - 25;
  2. int* ptr = (void*) ((-4) + 4);
  3. int* ptr = (0 * ((0 * 25) * 3);
  4. int* ptr = (void*) !(9);
  5. int* ptr = ((1 + 1) == 25);

shall make ptr, per standard, a null pointer.


  • Am I correct or is there anything wrong about my concerns?

I am looking for any part of the C standard which invalidates this thesis.

As far as I searched, there shouldn´t be a duplicate of this question on Stack Overflow.

like image 354
RobertS supports Monica Cellio Avatar asked May 11 '20 16:05

RobertS supports Monica Cellio


People also ask

Is a null pointer 0?

The null pointer constant is always 0. The NULL macro may be defined by the implementation as a naked 0 , or a cast expression like (void *) 0 , or some other zero-valued integer expression (hence the "implementation defined" language in the standard).

Is null integer or pointer?

NULL itself is not a pointer, it is a macro that can be used to initialize a pointer to the null pointer value of its type. When compared to a pointer, it compares equal if the pointer is a null pointer and unequal if the pointer is a valid pointer to an object of its type.

Can I assign null to a pointer?

It is always a good practice to assign the pointer NULL to a pointer variable in case you do not have exact address to be assigned. This is done at the time of variable declaration. A pointer that is assigned NULL is called a null pointer.

How do I return a null pointer in C++?

Just return '0' (zero). That is the representation of a null pointer in C++. nullptr would be better, but seriously, use std::find_if and preferably a std::vector<Person> without the pointer.


2 Answers

You are correct that all of these are valid.

Section 6.6 of the C standard states:

1

constant-expression:
    conditional-expression

...

3 Constant expressions shall not contain assignment, increment, decrement, function-call,or comma operators, except when they are contained within a subexpression that is not evaluated.

...

6 An integer constant expression shall have integer type and shall only have operands that are integer constants,
enumeration constants, character constants, sizeof expressions whose results are integer constants, _Alignof expressions, and floating constants that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the sizeof or _Alignof operator.

Each of the expressions in your examples fit this description, i.e.:

  • All operands are integer constants
  • The expression is a conditional-expression (i.e. doesn't use assignment or comma operators) with no increment, decrement, or function call operators
  • Evaluates to 0

So all are valid ways to assign NULL to a pointer.

Some examples that are not integer constant expressions:

int x = 1;
int *ptr1 = (3, 0);    //  invalid, comma operator not allowed
int *ptr2 = (x = 0);   //  invalid, assignment not allowed
int *ptr3 = x - 1;     //  invalid, an operand is not an integer constant
like image 163
dbush Avatar answered Oct 21 '22 16:10

dbush


Yep.

[C99 6.6/6]: An integer constant expression shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, and floating constants that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the sizeof operator.

Note that this is not the case in C++, where null pointer constants are defined differently:

[conv.ptr]/1: A null pointer constant is an integer literal ([lex.icon]) with value zero or a prvalue of type std​::​nullptr_­t. [..]

like image 29
Asteroids With Wings Avatar answered Oct 21 '22 15:10

Asteroids With Wings