请考虑以下代码:
#include <iostream>
#include <algorithm>
#include <numeric>
int main()
{
volatile auto width = uint64_t(5);
alignas(16)
char runtime[width]; std::iota(runtime,runtime+width,'1');
auto out = [](auto& curr) { std::cout << curr; };
auto capt_ref_to_runtime_bound_arr = [&runtime,width,out](auto &curr) {
std::for_each(runtime, runtime+width, out);
std::cout << " and width="
<< sizeof(runtime) / sizeof(*runtime)
<< '\n';
};
// clang code crashes even if below is commented out.
// std::for_each(runtime,runtime+width,capt_ref_to_runtime_bound_arr);
}
关于[&runtime]
捕获
GCC似乎将int(&)[width]
拒绝为char *
(请参阅下面的wandbox)
clang刚崩溃成红色文本块(参见下面的wandbox)
后来,我跑到N3639,它说一些功能被切断了(例如上面演示中的sizeof实际上是不合格的)。但为什么不编译器向我解释这些截止?如果标准允许这种捕获,它们如何定义它?
<小时/> ASM:godbolt.org/g/ptRRRp
GCC 7.2 -O1:wandbox.org/permlink/30muSDtbxZYeGV2p
clang 5.0 -O1:wandbox.org/permlink/yvvRhBLFXzzxmihi
答案 0 :(得分:11)
C ++标准(Bjarne Stroustrup):
数组元素的数量,数组绑定,必须是a 常数表达(§C.5)。如果需要变量边界,请使用 向量(§3.7.1,§16.3)。例如:
void f(int i) { int v1[i] ; / / error: array size not a constant expression vector<int> v2(i) ; / / ok }
因此,在当前和过去的所有C ++标准中,该代码都是格式错误的。 Variable Length Arrays是C99功能而非C ++功能。
答案 1 :(得分:1)
C ++中的可变长度数组是GNU扩展。曾经有一些计划将它们添加到语言中(以比GNU扩展更受限制的方式)。其中一个挑战是C ++类型系统假设类型具有恒定的大小并且在编译时完全布局(否则,模板元编程将不像现在那样工作)。
在以前的GCC版本中,有时可以在模板中使用可变修改的类型,但这应该已经修复。
答案 2 :(得分:1)
[问题所有者]
看起来N3639已移至Array Extensions TS N3830,然后在2013-10-10将阵列TS移至widthdrawn。
VLA尚未在社区中获胜。