标准如何定义捕获运行时绑定数组?

时间:2017-11-06 06:59:53

标签: c++ arrays gcc clang c++17

请考虑以下代码:

#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]捕获

  1. GCC似乎将int(&)[width]拒绝为char *(请参阅下面的wandbox)

  2. clang刚崩溃成红色文本块(参见下面的wandbox)

  3. 后来,我跑到N3639,它说一些功能被切断了(例如上面演示中的sizeof实际上是不合格的)。但为什么不编译器向我解释这些截止?如果标准允许这种捕获,它们如何定义它?

    <小时/> ASM:godbolt.org/g/ptRRRp

    GCC 7.2 -O1:wandbox.org/permlink/30muSDtbxZYeGV2p

    clang 5.0 -O1:wandbox.org/permlink/yvvRhBLFXzzxmihi

3 个答案:

答案 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尚未在社区中获胜。

cppreference.com/w/cpp/experimental

open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3820.html