参数仅用于constexpr函数体内未评估的上下文中

Alb*_*ert 5 c++ constexpr c++14

下面的代码已成功使用gcc 5.3.0编译,但无法使用clang 3.7.0进行编译.在两种情况下,我都使用相同命令行选项的在线coliru编译器:-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;
}
Run Code Online (Sandbox Code Playgroud)

clang拒绝它有以下错误:

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

由于两个编译器之间存在这种差异,我想知道这是否是一段有效的代码.如果没有,我想更好地理解为什么会这样.

Den*_*isS 1

你们正在将价值观混合const在一起constexprconstexpr的定义是编译时已知的值。但该argc变量仅在运行时已知(它是传递给可执行文件的许多参数)。所以你不能将它分配给另一个constexpr变量 - res_fooconstexpr从定义中删除res_foo将使您的代码可编译。

const和之间的区别constexpr可以简化为如下所示:
const- 我不会更改此值
constexpr- 该值在编译时已知,并且我不会更改它

我的猜测是 GCC 能够使用 O2 编译此代码,因为您没有使用参数arg_foo并且其大小在编译时已知。但它在语法上仍然不正确 - 编译器应该发出错误,因为非 constexpr 值被分配给 constexpr 变量。