【问题标题】:Why am I not getting a compile error when declaring a C array with variable size?为什么在声明具有可变大小的 C 数组时没有出现编译错误?
【发布时间】:2009-03-30 19:46:01
【问题描述】:

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

但是,我注意到如果我没有显式初始化数组,我不会收到任何错误(是的,它不会在堆栈上,但我想知道是否没有错误)。 例如下面的代码因为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,除非我另有说明。

【问题讨论】:

    标签: c arrays


    【解决方案1】:

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

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

    【讨论】:

    • 该死的,我还没有意识到 gcc 现在默认为 c99。我用 g++ 太久了。
    • @Uri 对你的问题没有 +1,因为你的诅咒。
    【解决方案2】:

    我认为你需要选择你的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’
    

    对比

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 我明白,但为什么我能编译第二个?
      【解决方案4】:

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

      error: variable-sized object may not be initialized
      

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

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

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

      第二个例子没有这个问题,因为你没有对array2的大小做出任何隐含的声明。

      希望对你有帮助,

      埃里克·梅尔斯基

      【讨论】:

        猜你喜欢
        • 2013-03-06
        • 2014-08-18
        • 2015-03-24
        • 2012-03-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多