没有给定维度的 C++ 结构数组成员(灵活的数组成员?)

C++ struct array member without given dimension (flexible array member?)

我编译并 运行 下面的 C++ 代码,盲目地尝试像在 C:

中那样创建一个灵活的数组成员
#include <iostream>

template <typename T>
struct Vector {
    int length;
    T ts[];
};

Vector<int> ts = {
    3,
    {10, 10, 10},
};


int main() {
    std::cout << sizeof(ts) << std::endl;
    std::cout << ts.data[1] << std::endl;
    return 0;
}

代码可以正常编译和运行,并给出与 C 在相同情况下相同的输出(它输出 4,然后输出 10)。

现在,根据this answer from 2010 what I have written should not be valid C++. Furthermore, according to this wikipedia article,"C++ does not have flexible array members"。

我的问题是,我在上面的代码中实际使用了哪个 C++ 功能,特别是在“T ts[];”这一行?该代码是否确实按照我认为的一般方式执行,或者它是未定义的行为?

这是 C 和 C++ 之间的差异之一。 灵活数组成员 在 C 中有效,但在 C++ 中无效。

就是说,许多现代编译器将 C 编译为 C++ 的一个子集,只有在您启动编译器错误诊断时才小心。

David Tribble 在他的 Incompatibilities Between ISO C and ISO C++ 页面上花费了一些时间,他专门解决了这个问题:

C++ does not support flexible array members.

(This feature might be provided as an extension by some C++ compilers, but would probably be valid only for POD structure types.)

所以是的,这是未定义的行为。编写这样的东西的正确方法(在 C 和 C++ 中)是给它一个非零维度:

template <typename T>
struct Vector {
    int length;
    T ts[1];
};

您还有另一个问题:必须为所述对象分配内存。仅仅指定一个初始值设定项是不够的。就存在对此类事物的每次访问而言,编译器只会认为它是其最小大小。

“range hack” 之所以这样称呼,是因为程序员明确 uses/abuses C(和 C++)违反范围边界来做一些棘手的事情的能力。

这样做的后果很多,包括无法将这些东西存储在任何标准容器中,或按值传递它们,或做大多数避免通过指针处理它的事情。它有它的位置,但对于绝大多数用例,C++ 有更好的选择。