声明一个负长度的数组

19

当你创建一个负长度的数组时,C语言会发生什么?

例如:

int n = -35;

int testArray[n];

for(int i = 0; i < 10; i++)
    testArray[i]=i+1;

这段代码能够编译通过(启用-Wall选项时没有警告),似乎可以对testArray[0]进行赋值而没有问题。但是,如果超出了数组范围,就会出现段错误或非法指令错误,并且从数组中读取任何内容都会显示"Abort trap"(我不熟悉这个错误)。我意识到这有点学术性质,希望在实际生活中永远不会出现,但是C标准是否有特别的方法来处理这样的数组?还是这因编译器而异?


for 语句的末尾有一个意外的分号 (;),我想是这个问题的原因... - Arun
3个回答

26

这是未定义行为,因为它违反了“应该”约束:

C99 §6.7.5.2:

如果大小是不是整数常量表达式的表达式......每次评估时它都应该大于零。


2
+1,确切的答案。但我发现编译器还不能对这种代码进行静态分析,并至少发出警告,这令我感到非常失望。我也用 clang-analyse 进行了测试,但没有改善。 - Jens Gustedt

4

我认为这是未定义行为,但请不要引用我。

这会在gcc中产生错误error: size of array 'testArray' is negative

int testArray[-35];

不过,正如你所见:

int n = -35;
int testArray[n];

即使使用-Wall和-W选项,也不会出现错误。

但是,如果您使用-pedantic标志,gcc将警告ISO C90禁止变长数组。


它实际上是做什么的?我猜它将其解释为无符号,因此您会得到(MAX_INT-35) - Martin Beckett
1
@Martin Beckett:由于这是未定义行为,编译器可以自由地做任何事情,即使它们是不合理的行为,因为分配负长度数组是一种可编译的无意义操作。如果我被允许重新设计C语言,我会将数组长度声明和索引设置为“unsigned int”,并要求编译器在使用“signed int”进行长度或索引操作时发出类型错误。 - Lie Ryan
这个问题被标记为C99,因此从标准的角度来看,变长数组方面是可以的。 - Jens Gustedt
@MartinBeckett,它只是疯狂地运行sizeof(testArray) == -35 * sizeof(int); - OwnageIsMagic

0

关于编译的Visual Studio错误信息,您可以使用-1来表示空数组。它期望整数,而您正在传递整数,因此不会出现编译器错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接