我编译并运行了以下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,我写的应该不是有效的C ++。此外,根据this wikipedia article,“ C ++没有灵活的数组成员”。
我的问题是,我在上面的代码中实际使用了哪个C ++功能,特别是在显示“
T ts[];
”的行上?该代码实际上执行了我认为的一般操作,还是未定义的行为? 最佳答案
这是C和C ++之间不同的事物之一。灵活数组成员在C中有效,但在C ++中无效。
就是说,许多现代的编译器将C编译为C ++的子集,只有当您加紧编译器错误诊断时,才要小心。
大卫·特里布尔(David Tribble)在他的Incompatibilities Between ISO C and ISO C++页面上花了一点时间,他专门解决了这个问题:
C ++不支持灵活的数组成员。
(此功能可能是某些C ++编译器的扩展功能,但可能仅对POD结构类型有效。)
是的,这是未定义的行为。编写这样的东西的正确方法(在C和C ++中)是给它一个非零维:
template <typename T>
struct Vector {
int length;
T ts[1];
};
您还有另一个问题:必须为所述对象分配内存。仅指定初始化器是不够的。只要存在对此类事物的每次访问,编译器都只会认为这是其最小大小。
之所以称其为“范围限制”,是因为程序员明确地使用/滥用C(和C ++)的能力来违反范围界限以进行棘手的事情。
这样做的后果是很多的,包括无法将这些东西存储在任何标准容器中,或者无法按值传递它们,或者无法执行大多数避免通过指针对其进行处理的事情。它有它的位置,但是对于绝大多数用例来说,C ++具有更出色的选择。
关于c++ - 没有给定维数的C++ struct数组成员(灵活的数组成员?),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46108144/