ISO C90禁止可变长度阵列

时间:2012-04-19 18:17:40

标签: c variable-length-array

我正在动态计算数组的大小。类似的东西:

void foo(size_t limit)
{
  char buffer[limit * 14 + 1];
}

但只是GCC编译器说:

error: ISO C90 forbids variable length array ‘buffer’

搜索SO我发现this answer

C99§6.7.5.2:

  

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

因此,我将大小限制类型变量重新声明为:

void foo(const size_t limit)

但它继续向我发出警告。这是GCC的错误吗?

6 个答案:

答案 0 :(得分:10)

const - 对变量进行限定并不会使它成为编译时常量(有关整数常量表达式的定义,请参阅C996.6§6),并且在引入之前具有C99的可变长度数组,数组大小需要是编译时常量。

很明显const - 限定变量并不使它成为编译时常量,特别是在函数参数的情况下,在调用函数之前不会对其进行初始化。

我看到了您的问题的以下解决方案:

  • 通过-std=c99-std=gnu99
  • 将代码编译为C99
  • 通过malloc()
  • 分配您的缓冲区
  • 使用alloca()(如果可用),这是您可以使用C90最接近可变长度数组
  • 选择始终使用的最大缓冲区大小,如果给定的limit参数溢出
  • ,则失败

作为旁注,即使C99允许可变长度数组,使用具有静态存储持续时间的整数变量的值作为具有静态存储持续时间的数组的大小仍然是非法的,无论const - 鉴定:虽然如果整数变量在同一个翻译单元中初始化,但是原则上没有什么可以阻止这种情况,你必须使用具有明显定义的特殊情况变量,这些变量的定义位于不同的翻译单元中并且必须不允许暂定定义或需要多个编译过程,因为在解析整个翻译单元之前,暂时定义的变量的初始化值是未知的。

答案 1 :(得分:4)

c90不允许可变长度数组。但是,您可以使用c99 gcc ompiler来完成这项工作。

您正在使用c90 gcc进行编译,但正在查看c99规范:)

答案 2 :(得分:4)

const不会在C中引入常量,而是只读变量。

#define SIZE 16
char bla[SIZE];   // not a variable length array, SIZE is a constant

const int size 16;
char bla[size];   // C99 variable length array, size is not constant

答案 3 :(得分:2)

不,这不是一个错误。您无法在C90中使用VLA。当你宣布

const size_t limit

这不是一个常量表达式。常量表达式类似于文字值666

请注意,在这方面,C与C ++显着不同。甚至像这样的常量

const int i = 666;

不是C中的常量表达式。这是在C中通常使用#define声明常量值的主要原因。

答案 4 :(得分:0)

正如您的问题所写,这是来自C99,而不是C90,您需要针对C99进行编译才能使用可变长度数组。

答案 5 :(得分:0)

const限定变量不是标准意义上的整数常量表达式。这必须是文字常量,枚举常量sizeof或由这些常量组成的表达式。

如果可以,请切换到C99。 gcc选项为-std=c99(如果您需要gnu扩展名,则为gnu99。)