C++ constexpr函数实际上可以接受非常量表达式作为参数吗?

God*_*der 10 c++ function constexpr c++11

我已经定义了一个constexpr函数如下:

constexpr int foo(int i)
{
    return i*2;
}
Run Code Online (Sandbox Code Playgroud)

这就是主要功能:

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;
}
Run Code Online (Sandbox Code Playgroud)

该程序是在OS X 10.8下用命令clang ++编译的.我很惊讶编译器没有产生关于foo(i)不是常量表达式的任何错误消息,并且编译的程序实际上工作正常.为什么?

Die*_*ühl 23

constexprC++ 中函数的定义使得函数保证能够在调用时生成常量表达式,以便在评估中仅使用常量表达式.但是,如果未在结果中使用结果,则评估是在编译时还是在运行时进行constexpr(请参阅此答案).将非常量表达式传递给a时constexpr,可能无法获得常量表达式.

但是,您的上述代码不应该编译,因为i它不是一个常量表达式,它可以明确地用于foo()生成结果,然后将其用作数组维度.似乎clang实现了C风格的可变长度数组,因为它为我生成了以下警告:

warning: variable length arrays are a C99 feature [-Wvla-extension]
Run Code Online (Sandbox Code Playgroud)

一个更好的测试,看看某个东西是否确实是一个常量表达式,是用它来初始化a的值constexpr,例如:

constexpr int j = foo(i);
Run Code Online (Sandbox Code Playgroud)