为什么我不能初始化一个可变大小的数组?

时间:2011-07-09 13:02:22

标签: c++ arrays initialization

只要变量是const,初始化可变大小的数组时GCC就不会出错,但是当它不是时,它就不会编译。

这背后的原因是什么?这样做有什么不妥:

int size = 7;
int test[size] = {3, 4, 5};

根本不会编译,但如果我没有初始化test []那么它会编译!这对我来说没有任何意义,因为据我所知,无论什么(这意味着我使用的整数文字都不是真的),需要根据其大小(7个整数)来使堆栈框架适合这个数组。如果我没有弄错的话,有任何意义,那么如果我初始化它会有什么不同呢?

我疯狂的C ++设计问题中的另一个......

谢谢!

6 个答案:

答案 0 :(得分:9)

  • 数组的大小必须是常量整数表达式。
  • 积分文字是一个常量积分表达式。 (int arr[5];
  • 用常量表达式初始化的常量积分变量是常量表达式。 (const int j = 4; const int i = j; int a[i];

  • 使用非常量表达式初始化的常量变量不是常量表达式

     int x = 4;  // x isn't constant expression because it is not const
     const int y = x; //therefore y is not either
     int arr[y]; //error)
    

答案 1 :(得分:5)

它实际上更像是一个疯狂的C99设计问题,因为可变长度数组是C99的一个特性,gcc允许在C ++中作为扩展。

在C99中,6.7.8 / 3表示“要初始化的实体的类型......不是可变长度数组类型”,因此gcc刚刚使用与C99要求相同的扩展规则。

C99基本原理文件没有说明为何无法初始化VLA。我可以推测这可能是因为初始化程序中存在多余元素的风险,如果为大小提供的值结果小于初始化程序。但我不知道。

答案 2 :(得分:4)

From http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html“ISO C99允许使用可变长度自动数组,作为扩展,GCC在C90模式和C ++中接受它们。”

您的程序在c ++中无效,gcc将其编译为“扩展名”。您可能不得不问gcc的作者他们为什么决定以这种方式实施。

答案 3 :(得分:4)

如果您使用const int size = 7;,某些编译器会允许此操作。从理论上讲,编译器可以发现它是常量大小但那样做。

答案 4 :(得分:3)

代码在标准C ++中无效。

根据 C ++标准(8.3.4.1)数组大小必须是常量表达式

C ++中不允许使用变量长度数组,因为C ++为此提供了std :: vector。

可变长度数组是在C ++基于c98从C标准扩展后在C99中引入的一个特性。 C ++已经有std::vector来提供变量长度数组的功能,所以C ++标准从不允许变长数组作为标准的一部分。

如果您的编译器支持它,则通过编译器扩展。使用-pedantic选项进行编译,它将通知您相同的警告说它被ISO C ++禁止

答案 5 :(得分:0)

我不确定gcc设计人员在实施此扩展时的意图,但gcc扩展程序这样工作的一个可能原因是:

int is1[2] = {1}

在没有警告的情况下编译,合理地假设用户想要{1,0}

int is2[1] = {1,2};

编译警告,编译器应该做什么?

int i;
cin >> i;
int is3[i] = {1,2}
啊哈,警告或不警告?