ISO C90禁止可变长度arrays

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

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

但只是GCC编译器说:

 error: ISO C90 forbids variable length array 'buffer' 

搜索SO我发现这个答案 :

C99§6.7.5.2:

如果size是一个不是整数常量表达式的表达式……每次计算它时,它的值应大于零。

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

 void foo(const size_t limit) 

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

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

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

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

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

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

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

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

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 

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

 const size_t limit 

这不是一个恒定的表达。 常量表达式将类似于字面值666

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

 const int i = 666; 

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

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

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

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