C++ constexpr返回数组,gcc警告
我编写了一个返回数组的constexpr函数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
#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]
^