6

我正在动态计算数组的大小。就像是:

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

但只是 GCC 编译器说:

error: ISO C90 forbids variable length array ‘buffer’

搜索所以我找到了这个答案

C99 §6.7.5.2:

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

所以,我重新声明了大小限制类型变量:

void foo(const size_t limit)

但它继续给我警告。这是 GCC 错误吗?

4

6 回答 6

12

const- 限定变量不会使其成为编译时常量(有关整数常量表达式的定义,请参见 C99 6.6 §6 ),并且在使用 C99 引入可变长度数组之前,数组大小需要在编译时常数。

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

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

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

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

于 2012-04-19T20:08:00.993 回答
6

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 a constant
于 2012-04-19T18:21:18.567 回答
3

C90 不允许变长数组。但是,您可以使用c99-gcc编译器来完成这项工作。

您正在编译c90-gcc但正在查看 C99 规范。

于 2012-04-19T18:19:33.433 回答
2

不,这不是错误。您不能在 C90 中使用 VLA。当你宣布

const size_t limit

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

请注意,C 在这方面与 C++ 有很大不同。即使是这样的常数

const int i = 666;

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

于 2012-04-19T18:19:46.813 回答
0

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

于 2012-04-19T18:19:53.287 回答
0

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

如果可以,请切换到 C99。gcc 选项是-std=c99(或 gnu99,如果你想要 gnu 扩展。)

于 2012-04-19T18:21:36.617 回答