简体   繁体   English

ISO C90 禁止变长数组

[英]ISO C90 forbids variable length array

I'm dynamically calculating the size of an array.我正在动态计算数组的大小。 Something like:就像是:

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

But just GCC compiler says:但只是 GCC 编译器说:

error: ISO C90 forbids variable length array ‘buffer’

searching on SO I found this answer :搜索 SO 我找到了这个答案

C99 §6.7.5.2: C99 §6.7.5.2:

If the size is an expression that is not an integer constant expression... ...each time it is evaluated it shall have a value greater than zero.如果大小是一个不是整数常量表达式的表达式... ...每次计算它时,它的值都应大于零。

So, I did the re-declaration of size limit type variable to:因此,我将大小限制类型变量重新声明为:

void foo(const size_t limit)

But it continues to give warning for me.但它继续给我警告。 Is this a GCC bug?这是 GCC 错误吗?

const -qualifying a variable doesn't make it a compile-time constant (see C99 6.6 §6 for the defintion of an integer constant expression ), and before the introduction of variable-length arrays with C99, array sizes needed to be compile-time constants. const限定变量不会使其成为编译时常量(有关整数常量表达式的定义,请参见 C99 6.6 §6),并且在使用 C99 引入可变长度数组之前,需要编译数组大小-时间常数。

It's rather obvious that const -qualify a variable doesn't make it a compile-time constant, in particular in case of function parameters which won't be initialized until the function is called.很明显, const -qualify 变量不会使其成为编译时常量,特别是在函数参数被调用之前不会被初始化的情况下。

I see the following solutions to your problem:我看到以下解决您的问题的方法:

  • compile your code as C99 via -std=c99 or -std=gnu99通过-std=c99-std=gnu99将您的代码编译为 C99
  • allocate your buffer via malloc()通过malloc()分配缓冲区
  • use alloca() if available, which is the closest you can come to variable-length arrays with C90如果可用,请使用alloca() ,这是使用 C90 最接近可变长度数组的方法
  • choose a maximum buffer size which is always used and fail if the given limit argument overflows选择一个始终使用的最大缓冲区大小,如果给定的limit参数溢出则失败

As a side note, even though C99 allows variable-length arrays, it's still illegal to use the value of an integer variable with static storage duration as size for an array with static storage duration, regardless of const -qualification: While there's nothing which prevents this in principle if the integer variable is initialized in the same translation unit, you'd have to special-case variables with visible defintion from those whose definition resides in a different translation unit and would either have to disallow tentative defintions or require multiple compilation passes as the initialization value of a tentatively defined variable isn't known until the whole translation unit has been parsed.作为旁注,即使 C99 允许可变长度数组,使用具有静态存储持续时间的整数变量的值作为具有静态存储持续时间的数组的大小仍然是非法的,无论const限定如何:虽然没有什么可以阻止原则上,如果整数变量是在同一个翻译单元中初始化的,那么您必须将具有可见定义的特殊变量与定义位于不同翻译单元的那些变量分开,并且必须禁止暂定定义或需要多次编译通过因为在整个翻译单元被解析之前,暂定定义的变量的初始化值是未知的。

const does not introduce a constant in C but a read-only variable. const在 C 中没有引入常量,而是引入了只读变量。

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

but

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

C90 doesn't allow variable length arrays. C90 不允许变长数组。 However, you can use the c99-gcc compiler to make this work.但是,您可以使用c99-gcc编译器来完成这项工作。

You are compiling with c90-gcc but looking at C99 specifications.您正在使用c90-gcc进行编译,但查看 C99 规范。

No it is not a bug.不,这不是错误。 You can't use a VLA in C90.您不能在 C90 中使用 VLA。 When you declared当你声明

const size_t limit

that is not a constant expression.这不是一个常量表达式。 A constant expression would be something like a literal value 666 .常量表达式类似于字面值666

Note that C differs significantly from C++ in this regard.请注意,C 在这方面与 C++ 有很大不同。 Even a constant like this即使是这样的常数

const int i = 666;

is not a constant expression in C. This is the primary reason why constant values are typically declared with #define in C.不是 C 中的常量表达式。这是在 C 中通常使用#define声明常量值的主要原因。

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

A const qualified variable is not an integer constant expression in the sense of the standard. const限定变量不是标准意义上的整数常量表达式。 This has to be a literal constant, an enumeration constant, sizeof or some expression composed with these.这必须是文字常量、枚举常量、 sizeof或由这些组成的某些表达式。

Switch to C99 if you may.如果可以,请切换到 C99。 The gcc option is -std=c99 (or gnu99 if you want gnu extension.) gcc 选项是-std=c99 (或者 gnu99,如果你想要 gnu 扩展。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM