在尝试向某人解释为什么C ++静态数组无法动态调整大小时,我发现gcc不同意我的看法。鉴于在编译时不知道数组的维 argc ,以下代码如何编译?
#include <iostream>
int main(int argc, char* argv[]) {
int array[argc];
for(int i = 0; i < argc; i++) array[i] = argv[i][0];
for(int i = 0; i < argc; i++) std::cout << i << ": " << char(array[i]) << std::endl;
//for(int i = 0; i < 100; i++) { std::cout << i << " "; std::cout.flush(); array[i] = 0; }
return 0;
}
我使用gcc 4.2.1进行了测试,并指定了-Wall,而没有从编译器那里得到一个脏看。如果我取消注释最后一个循环,当我分配给 array [53] 时会出现段错误。
我之前在声明数组之前和之后放置了保护数组,并用零填充它们,确定程序必须将其堆栈的一部分废弃,但是gcc重新排序了变量。堆栈,这样我就无法观察到任何数据损坏。
显然,我并不是想让这段代码“运转”。我只是想了解为什么gcc甚至认为它可以编译代码。任何提示或解释都将非常感激。
更新:感谢所有人提供的有用且快速的回复!
答案 0 :(得分:10)
可变长度数组(VLA)是C99的一部分,并且长期以来一直受到gcc的支持:
http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html
请注意,在C90和C ++代码中使用VLA是非标准的,但gcc作为扩展支持。
答案 1 :(得分:6)
这是Variable Length Array,这是C99标准的一部分。它不是C ++的一部分。
您也可以使用alloca
函数,该函数也不是标准C ++,但受到广泛支持:
int main(int argc, char* argv[])
{
int* array = (int*) alloca( argc * sizeof(int) );
array[0] = 123;
// array automatically deallocated here. Don't call free(array)!
}
答案 2 :(得分:3)
这些被称为可变长度数组(自C99起可用)并且只能作为自动变量声明 - 尝试将static
放在前面,编译器将拒绝它。它只涉及使用变量递增堆栈指针而不是使用常量偏移量,而不是更多。
在引入可变长度数组之前,使用alloca
函数在堆栈上分配可变大小的对象。
答案 3 :(得分:2)
可变大小的基于堆栈的数组是G ++扩展,在那里完全合法。然而,它们不是标准的。在大多数实现中,基于堆栈的数组确实可以变化,但标准并没有强制要求。
答案 4 :(得分:2)
除了使用常量表达式之外,无法调整C ++中的数组。通过非常量大小的数组是C99的一部分或GCC强加给我们的可怕扩展。在编译C ++代码时,可以使用-pedantic
标志去除大部分GCC废话。