C++ constexpr返回数组,gcc警告

C++ constexpr返回数组,gcc警告,c++,arrays,gcc,constexpr,gcc-warning,C++,Arrays,Gcc,Constexpr,Gcc Warning,我编写了一个返回数组的constexpr函数 #include <iostream> constexpr auto get_str(void) -> const char(&)[4] { return { 'T', 'E', 'S', 'T' }; } constexpr int sum(const char(&str)[4]){ return str[0] + str[1] + str[2] + str[3]; } int main

我编写了一个返回数组的constexpr函数

#include <iostream>

constexpr auto get_str(void)
-> const char(&)[4] {   
    return { 'T', 'E', 'S', 'T' };
}

constexpr int sum(const char(&str)[4]){
    return str[0] + str[1] + str[2] + str[3];
}

int main(void){

    constexpr int s = sum(get_str());

    std::cout << s << std::endl;

    return 0;
}
在这种情况下,警告是否正确?即使在运行时(仅在编译过程中)从未实际调用过constexpr函数,但这样从constexpr函数返回数组是否不正确

函数从未在运行时实际调用,仅在运行期间调用 汇编

完全没有标准的保证。编译器完全有权在运行时调用它


constepr
如果编译器在编译时调用临时变量,它永远不会消亡。编译器没有义务。

clang3.4
不编译此代码,因为
sum(get_str())
不是constexpr,据我所知
clang3.4
在这里是正确的,这一行():

生成以下错误:

error: constexpr variable 's' must be initialized by a constant expression
constexpr int s = sum(get_str());
              ^   ~~~~~~~~~~~~~~

note: read of temporary whose lifetime has ended
return str[0] + str[1] + str[2] + str[3] 
       ^
它不是有效的
constexpr
,原因有二。这会调用未定义的行为,总结一下,
5.19节说:

条件表达式e是核心常量表达式,除非

并包含以下项目符号:

具有未定义行为的操作

在其生命周期之外的访问将是。我们从
12.2
临时对象部分了解到,在这种情况下,临时对象的寿命不会延长,该部分说明:

第二个上下文是将引用绑定到临时上下文。117 引用绑定到的临时文件或 引用绑定到的子对象的完整对象 在引用的生存期内持续存在,但

并包括以下项目符号:

临时绑定到函数中返回值的生存期 返回语句(6.6.3)未扩展;临时文件被销毁 在return语句中完整表达式的末尾

因此,尽管常数表达式确实不能保证在翻译时进行计算,但我们在
5.19节
常数表达式中有一个注释提到了这一点(重点如下):

注:在翻译过程中,可以对常量表达式求值。-结束 注]

即使得到保证,我们仍然不允许调用未定义的行为

第二个问题是constexpr引用必须是静态存储持续时间或函数的对象,在其中提到了这一点:

引用常量表达式是左值核心常量表达式 用静态存储持续时间或函数指定对象的

据我所知,这在第5.19节常数表达式第4段中有介绍,其中说:

引用类型的每个非静态数据成员引用具有 静态存储持续时间或函数


您可以使用
std::array
按值返回constexpr静态数组,而不是返回引用。@MikaelPersson谢谢,我曾尝试过使用std::array,但我的完整代码做了一些奇怪的事情,需要编译时转换为const char*,我无法执行&arr[0]在一个常量表达式中。它没有义务,但它肯定是在编译时查看程序集时这样做的。我想这个警告是有道理的,如果不能保证,我会避免这样做。我知道这是老问题,但我在另一个问题中看到了这一点,它在这里是相关的:“除了能够在编译时对表达式求值外,我们还希望能够要求在编译时对表达式求值;变量定义前面的constexpr执行此操作(并暗示const):“
constexpr int s = sum(get_str());
error: constexpr variable 's' must be initialized by a constant expression
constexpr int s = sum(get_str());
              ^   ~~~~~~~~~~~~~~

note: read of temporary whose lifetime has ended
return str[0] + str[1] + str[2] + str[3] 
       ^