The argument is used only in an unvalued context within the body of the constexpr function

The following part of the code was successfully compiled with gcc 5.3.0, but not compiled with clang 3.7.0. I used coliru online compilers with the same command line options in both cases: -std = C ++ 14 -O2 -Wall -pedantic -pthread.

#include <cstdio> // Definition of constexpr function 'foo'. constexpr std::size_t foo(const int& arg_foo) { return sizeof(arg_foo); } // Definition of function 'test'. void test(const int& arg) { // The following line produces an error with clang. constexpr std::size_t res_foo = foo(arg); // Print the result returned by the 'foo' function. std::printf("res_foo = %lu\n", res_foo); } // Definition of function 'main'. int main(int argc, const char* argv[]) { // Test function call. test(argc); // Return statement. return 0; } 

clang rejects it with the following error:

 error: constexpr variable 'res_foo' must be initialized by a constant expression constexpr size_t res_foo = foo(arg); ~~~~^~~~ 

Due to this difference between the two compilers, I wonder if this is really a valid piece of code. If not, I would like to better understand why this is so.

+5
source share
2 answers

You mix const and constexpr together. The definition of constexpr is a value known at compile time. But the argc variable is known only at runtime (this is the number of arguments passed to your executable). Therefore, you cannot assign it to another constexpr variable - res_foo . Removing constexpr from the res_foo definition will make your code compile.

The difference between const and constexpr can be simplified like this: const - I'm not going to change this value
constexpr - this value is known at compile time, and I'm not going to change it

I assume that GCC can compile this code with O2, since you are not using the arg_foo argument, and its size is known at compile time. But it is still syntactically incorrect - the compiler should throw an error, since the value of non-constexpr is assigned to the constexpr variable.

+1
source

The program is correct, since foo(arg) is an expression of the constant of the main value prvalue, as defined in C ++ 14 5.20 / 2. In particular, the lvalue-rvalue conversion is not performed during the evaluation, which makes it not constant.

0
source

Source: https://habr.com/ru/post/1241132/


All Articles