为什么在声明可变大小的C数组时,我没有收到编译错误?

时间:2009-03-30 19:46:02

标签: c arrays

我的理解一直是当我在堆栈上声明一个带有作为变量或参数的大小的数组时,我应该得到一个错误。

然而,我注意到如果我没有显式初始化数组,我没有得到任何错误(是的,它不会在堆栈上,但我想知道缺少错误)。 例如,由于array2:

,以下代码无法编译
#define N 30

void defineArrays(int n)
{
    int i,j;
    int array1[N] = {};

    int array2[n] = {};

    for(i=0; i<N; ++i) array1[i] = 0;

    for(j=0; j<n; ++j) array2[j] = 0;
}

但是下面的代码编译并运行,即使我从main发送了一个真实的n:

#define N 30

void defineArrays(int n)
{
    int i,j;
    int array1[N] = {};

    int array2[n];

    for(i=0; i<N; ++i) array1[i] = 0;

    for(j=0; j<n; ++j) array2[j] = 0;
}

我在这里缺少什么?它是否将array2声明为指针? 我正在使用gcc

更新:感谢所有回答的人。问题确实是我的gcc版本由于一些奇怪的原因而默认为C99(或者不是那么奇怪,也许我只是太老了),我错误地认为它默认为C90,除非我另有说明。

4 个答案:

答案 0 :(得分:14)

C99引入了具有可变长度阵列的能力,现在可在GCC中使用(尽管据报道它不完全符合标准)。在第二个示例中,您似乎正在利用该功能。

链接到GCC关于可变长度数组的信息:http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html

答案 1 :(得分:3)

我认为您需要选择C标准版本。

gcc -fsyntax-only -std=c89 -pedantic -x c -

<stdin>: In function ‘defineArrays’:
<stdin>:6: warning: ISO C forbids empty initializer braces
<stdin>:8: warning: ISO C90 forbids variable length array ‘array2’

VS

gcc -fsyntax-only -std=c99 -pedantic -x c -
<stdin>: In function ‘defineArrays’:
<stdin>:6: warning: ISO C forbids empty initializer braces

答案 2 :(得分:1)

使用初始化程序声明数组会强制数组为静态(在编译时创建),即使范围在函数内。编译器无法在编译时定义数组,因为它不知道'n'的值。

答案 3 :(得分:1)

当我用gcc编译第一个例子时,它给了我这个错误:

error: variable-sized object may not be initialized

我想这是不允许的,因为你不知道n会有多大,因此你无法确定它是否足以容纳你想要初始化的所有元素。也就是说,假设你有这样的代码:

int array2[n] = { 1, 2, 3, 4 };

这要求array2具有(至少)4个插槽。如果将n传入零,该怎么办?

第二个示例没有此问题,因为您没有对array2的大小做任何隐式声明。

希望有所帮助,

Eric Melski