我已经定义了一个constexpr函数,如下所示:
constexpr int foo(int i)
{
return i*2;
}
这就是主要功能:
int main()
{
int i = 2;
cout << foo(i) << endl;
int arr[foo(i)];
for (int j = 0; j < foo(i); j++)
arr[j] = j;
for (int j = 0; j < foo(i); j++)
cout << arr[j] << " ";
cout << endl;
return 0;
}
该程序在OS X 10.8下使用命令clang++进行编译。令我惊讶的是,编译器未产生有关foo(i)不是常量表达式的任何错误消息,并且编译后的程序实际上运行良好。为什么?
最佳答案
在C++中constexpr
函数的定义是这样的:保证函数在被调用时能够生成一个常量表达式,从而使得在评估中仅使用常量表达式。但是,没有指定评估结果是在编译时还是在运行时(如果结果未在constexpr
中使用)(请参见this answer)。当将非常数表达式传递给constexpr
时,您可能不会获得常数表达式。
但是,您上面的代码不应编译,因为i
不是一个常量表达式,foo()
显然使用该表达式来生成结果,然后将其用作数组维。似乎clang实现了C样式的可变长度数组,因为它为我产生了以下警告:
warning: variable length arrays are a C99 feature [-Wvla-extension]
判断某物是否确实是一个常数表达式的更好测试是使用它来初始化
constexpr
的值,例如:constexpr int j = foo(i);