Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to initialize a pointer using an object with 0 value [duplicate]

In the book "C++ Primer, 5th ed", section 2.4.4, the entire section explains about "constexpr". Then an exercise as below is given in the book:

Exercise 2.32: Is the following code legal or not? If not, how might you make it legal?

int null = 0, *p = null;

I understand that a quick way to fix it is to just change it to *p = nullptr, or NULL, or use reinterpret_cast. But I think the book's intention is to use something related to constexpr. So my question is, how would the above exercise be solved properly? (I think the book's intention is to init the value of p to 0, not the address of null.)

I made below trials but both failed at compilation:

trial 1, adding constexpr:

constexpr int null = 0; 
int *p = null;

trial 2, adding const;

const int null = 0;
int *p = null;

(I made this trial based on the wordings in book chapter 4.11.2, Other implicit conversions: "A constant integral value of 0 and the literal nullptr can be converted to any pointer type;")

Thank you in advance. (Reason being asked as a new question: this is asked as a new question in hope of finding a solution. there is another closely related question but no proposed solution was given Is this constexpr integer not a null pointer constant?)

like image 717
modeller Avatar asked Jun 13 '14 20:06

modeller


1 Answers

The actual wording from the standard (4.10 [conv.ptr]) is:

1 - A null pointer constant is an integral constant expression (5.19) prvalue of integer type that evaluates to zero or a prvalue of type std::nullptr_t. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type [...]

The problem with null is that although it is an integral constant expression with value zero, it is an lvalue (that is, it is the name of object) and so not a prvalue.

Some ways to obtain an integer constant prvalue:

constexpr int null = 0; 
int *p = +null;

By prefixing null with the unary arithmetic operator + we get a prvalue.

const int null = 0;
int *p = static_cast<int>(null);

static_cast to a non-reference type yields a prvalue.

like image 64
ecatmur Avatar answered Sep 28 '22 15:09

ecatmur