Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A little confused about constexpr functions

Tags:

c++

c++11

Consider the following code:

constexpr const int* address(const int& r)
{
   return &r;
}


int main()
{
   int x = 10;
   constexpr const int* p = address(x); //error

   _getch();
   return 0;
}

This is an error: "function call must have a constant value in a constant expression". Ok.

Two questions:

  1. If 'x' is declared static, there are no errors. Why?

  2. How is it possible to get a variable address during the compilation process? Aren't they allocated at run-time?

like image 688
Enzos Avatar asked Aug 10 '17 09:08

Enzos


3 Answers

If 'x' is declared static, there are no errors. Why?

This is because there is always exactly one x in the program. It has an address (somewhere in the .data segment under normal conditions).

Confusingly, both static and extern keywords specify the storage duration as static (they differ in linkage)

How is it possible to get a variable address during the compilation process? Aren't they allocated at run-time?

Variables with automatic, dynamic or thread storage durations are allocated at runtime. Static duration variables are allocated by the compiler. (The linker and OS can change the location, but they know how to fix all the references when they do)

like image 179
Caleth Avatar answered Oct 19 '22 00:10

Caleth


A pointer to a variable with static storage duration is a constexpr. You can see this in the following program:

int main() {
    static int x;
    int y;
    constexpr int* px = &x; // Compilation is successful
    constexpr int* py = &y; // Compilation will fail
}

See https://ideone.com/lc9u3E

px is an address constant expression. Here's a standard reference:

[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 21
Bathsheba Avatar answered Oct 18 '22 23:10

Bathsheba


The address of a variable with static storage duration is not known at compile time. It is only known at link time. A pointer to a variable with static storage duration can be used at compile time because the exact value of the address does not matter - pointer comparisons and casts are not allowed at compile time.

like image 41
pepsiman Avatar answered Oct 19 '22 00:10

pepsiman