Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

constexpr initializing with pointers

I am trying to initialize a constexpr declaration with a pointer to int which is a const object. I also try to define an object with a object that is not a const type.

Code:

#include <iostream>

int main()
{
constexpr int *np = nullptr; // np is a constant to int that points to null;
int j = 0;
constexpr int i = 42; // type of i is const int
constexpr const int *p = &i; // p is a constant pointer to the const int i;
constexpr int *p1 = &j; // p1 is a constant pointer to the int j; 
}

g++ log:

constexpr.cc:8:27: error: ‘& i’ is not a constant expression
constexpr.cc:9:22: error: ‘& j’ is not a constant expression

I believe it is because the objects in main have no fixed addresses, thus g++ is throwing error messages back at me; how would I correct this? Without using literal types.

like image 446
TheBlueCat Avatar asked Nov 21 '12 18:11

TheBlueCat


People also ask

Why does constexpr need to be static?

A static constexpr variable has to be set at compilation, because its lifetime is the the whole program. Without the static keyword, the compiler isn't bound to set the value at compilation, and could decide to set it later.

Should I use const with constexpr?

Use constexpr if the value of your variable is known at compile time. Use const in cases where the value is not known at compile time, or you can't use constexpr with the type even though you know it at compile time. In C++17, constexpr is not available for all types such as string.

What is the point of constexpr functions?

constexpr functions A constexpr function is one whose return value is computable at compile time when consuming code requires it. Consuming code requires the return value at compile time to initialize a constexpr variable, or to provide a non-type template argument.

Does constexpr take memory?

The alternatives don't have the all of the positives of static constexpr - you're guaranteed compile time processing, type safety, and (potentially) lower usage of memory (constexpr variables don't need to take up memory, they are effectively hard coded unless if possible).


1 Answers

Make them static to fix their addresses:

int main()
{
  constexpr int *np = nullptr; // np is a constant to int that points to null;
  static int j = 0;
  static constexpr int i = 42; // type of i is const int
  constexpr const int *p = &i; // p is a constant pointer to the const int i;
  constexpr int *p1 = &j; // p1 is a constant pointer to the int j; 
}

This is known as an address constant expression [5.19p3]:

An address constant expression is a prvalue core constant expression of pointer type that evaluates to the address of an object with static storage duration, to the address of a function, or to a null pointer value, or a prvalue core constant expression of type std::nullptr_t.

like image 163
Jesse Good Avatar answered Oct 17 '22 09:10

Jesse Good