c++ - 仅在 constexpr 函数体内的未计算上下文中使用的参数

标签 c++ c++14 constexpr

下面这段代码用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;
}

clang 拒绝它并出现以下错误:

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

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

最佳答案

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

constconstexpr 的区别可以简化成这样:
const - 我不会改变这个值
constexpr - 这个值在编译时是已知的并且我不会改变它

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

关于c++ - 仅在 constexpr 函数体内的未计算上下文中使用的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34925550/

相关文章:

c++ - 为什么在增加 -fconstexpr-steps 后无法解析常量表达式?

c++ - 非成员函数 begin()/cbegin() 及其constexpr-ness

c++ - 仅使用数值格式化 wx.TextCtrl - 浮点精度

c++ - 常量和重载构造函数

c++ - 如何访问嵌套在命名空间内的未命名空间变量?

c++ - 抛出 constexpr 函数

c++ - 为什么reinterpret_cast不是constexpr?

c++ - 2 名知道最大步数的玩家团队

c++ - 根据字符串检查 argv[]? (C++)

c++ - 将 std::vector 传递给构造函数并移动语义