GNU C++ extension implements compound literal differently form C99在某种意义上说,GNU C ++复合文字是一个临时对象并具有单行生命周期。
因此,此代码在尝试获取此类临时对象的地址时出现编译错误:
#include <iostream>
using namespace std;
#include <valarray>
int main() {
int n = 5;
std::valarray<int> arr((int[]){1,1,2,2,3}, n);
//^^^^^ error here, although the compound literal
// outlives the constructor
for (int i = 0; i < n; ++i)
cout << arr[i] << ' ';
cout << endl;
}
但是,通过将(int[]){1,1,2,2,3}
更改为(const int[]){1,1,2,2,3}
,此错误消失,代码runs OK。
然后似乎通过添加const
限定符,复合文字不再是临时的。
我知道const
引用可以将临时对象的生命周期延长到参考的生命周期,但我不知道这与这个问题有什么关系。
所以我的问题是,上面代码是C ++标准和/或GNU C ++扩展的明确定义的行为吗?
答案 0 :(得分:4)
由于它是GCC扩展,它当然不能由C ++标准定义。就标准而言,该计划并不完善。
GNU文档(根据您的链接)指出const
修饰符可能会改变行为:
作为优化,C ++编译器有时会为数组复合文字提供更长的生命周期:当数组出现在函数外部或具有const限定类型时。如果'foo'及其初始化程序具有'char * const'类型而不是'char *'的元素,或者'foo'是全局变量,则该数组将具有静态存储持续时间。
但继续建议:
但是,避免在编译为C ++的代码中使用数组复合文字可能是最安全的。
顺便说一句,从C ++ 11开始,有一个std::valarray
构造函数采用initializer_list
,因此以下是在没有GCC扩展的C ++ 11中格式良好的:
std::valarray<int> arr{1,1,2,2,3};