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

san*_*orn 3 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);
}
Run Code Online (Sandbox Code Playgroud)

关于[&runtime]捕获

  1. 海湾合作委员会似乎衰败int(&)[width]到了char *(见下面的wandbox)

  2. 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

msc*_*msc 11

C++标准(Bjarne Stroustrup):

数组的元素数量(数组绑定)必须是常量表达式(§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
}
Run Code Online (Sandbox Code Playgroud)

因此,在当前和过去的所有C++标准中,该代码都是错误的.可变长度数组是C99功能,而不是C++功能.

  • @sandthorn"*必须是一个常量表达式*"因此,如果不是,代码就会形成错误. (3认同)
  • @sandthorn它被认为是不良形式的计划.它不应该编译.编译器允许这样做,将其作为非标准扩展,并且从技术上讲,您不再使用C++.这些扩展不需要遵循常见的C++约定,也不需要与其他C++特性很好地交互.您需要参考编译器扩展文档. (3认同)
  • @sandthorn - 它从未成为任何标准版本的一部分.目前的提案可以在这里找到http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0785r0.html (3认同)