4

I've read the link about constexpr: https://en.cppreference.com/w/cpp/language/constexpr

It says that the constexpr specifier declares that it is possible to evaluate the value of the function or variable at compile time.

As my understanding, it means that a variable specified by constexpr may or may not be evaluated at compile time.

This link told me the same thing: constexpr variables are not compile-time values.

However, I made a test, which confused me: https://godbolt.org/z/9ajb4xKK8

As you see, the variable a must be evaluated at compile time, otherwise it can't be used to declare an array. And the variable s can't be specified by constexpr because the constructor of std::string can't be invoked at compile time.

In a word, it seems that this testing is telling me that constexpr MUST evaluate the value at compile time. Otherwise, how can the variable a be used to declare an array?

What did I wrongly understand?

EDIT

I know that a constexpr function can be invoked at runtime or at compile time. For example, if we pass a runtime paramater to a constexpr function, the function would be invoked at runtime, I understand that.

But it seems that a constexpr variable MUST be evaluated at compile time. Can I say that any constexpr variable MUST be evaluated at compile time?

Yves
  • 11,597
  • 17
  • 83
  • 180
  • you found one example where `constexpr` must be at compile time. There are other examples where it can be at runtime. – 463035818_is_not_an_ai Jul 15 '21 at 08:10
  • @463035818_is_not_a_number I understand that a `constexpr` function can be invoked at runtime or at compile time. But I don't understand how a `constexpr` variable can be evaluated at runtime instead of at compile time. As you see, if a `constexpr` variable can't be evaluated at compile time, such as `std::string s`, an error will be generated. So why can't we say that a `constexpr` variable MUST be evaluated at compile time? – Yves Jul 15 '21 at 09:09
  • I think `constinit` is more like what you expect. As I understand it `constexpr` is rather to be more explicit and expressive. Consider you want to use `x` in a context that requires a compile time constant, you can write `const int x = foo();` which is ok in any case, but later using `x` in a context taht requires a compile time constant can fail depending on `foo`. On the other hand `constexpr int x = foo();` will fail early when `foo` is not constexpr – 463035818_is_not_an_ai Jul 15 '21 at 09:31
  • actually I should do some reading and rephrase that into an answer... – 463035818_is_not_an_ai Jul 15 '21 at 09:34
  • btw last paragraph seems to contain a typo. "But it seems that [...]. So can i say that [exactly same ...]" – 463035818_is_not_an_ai Jul 15 '21 at 09:36
  • 1
    cppreference is written to "simplify" the standard, See [dcl.constexpr](https://eel.is/c++draft/dcl.constexpr) for formal definition. – Jarod42 Jul 15 '21 at 09:47
  • 1
    constexpr variables are compile time only, whereas constexpr functions are compile or runtime depending of context. – Jarod42 Jul 15 '21 at 09:49
  • *"constexpr variables are not compile-time values"*. It is mostly `mutable` which introduces exception as removing constness(constexpr-ness) of subobject. – Jarod42 Jul 15 '21 at 09:55
  • @Jarod42 Alright, I see...lol – Yves Jul 15 '21 at 09:55

1 Answers1

0

Firstly, the compiler used in your godbolt link (gcc 11.1) allows variable-length arrays. So a does not have to be a constant expression. i.e this snippet of code below will be accepted

int a = 5;
int arr[a];

But when you do need something to be a constant expression constexpr will allow you to use the variable/function in it.

constexpr - specifies that the value of a variable or function can appear in >constant expressions

For example, when you create an array using the std::array template, the size must be constant

So doing this is not OK

int a = 5;
std::array<int, a> arr;

On the other hand, constexpr allows a to be used in a constant expression, so you CAN do this

constexpr int a = 5;
std::array<int, a> arr;