问题描述
我正在动态计算数组的大小.像这样:
I'm dynamically calculating the size of an array. Something like:
void foo(size_t limit)
{
char buffer[limit * 14 + 1];
}
但是只有GCC编译器说:
But just GCC compiler says:
error: ISO C90 forbids variable length array ‘buffer’
在SO上搜索,我发现了此答案:
searching on SO I found this answer:
C99§6.7.5.2:
因此,我将尺寸限制类型变量重新声明为:
So, I did the re-declaration of size limit type variable to:
void foo(const size_t limit)
但是它继续向我发出警告.这是GCC错误吗?
But it continues to give warning for me. Is this a GCC bug?
推荐答案
const
-限定变量不会使其成为编译时常量(有关整数常量的定义,请参见C99 6.6§6)表达式),在引入带有C99的可变长度数组之前,数组大小必须是编译时常量.
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
-qualify变量不会使其成为编译时常量,尤其是在函数参数直到调用该函数才被初始化的情况下.
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.
我为您的问题找到了以下解决方案:
I see the following solutions to your problem:
- 通过
-std=c99
或-std=gnu99
将代码编译为C99 - 通过
malloc()
分配缓冲区 - 使用
alloca()
(如果可用),这是使用C90到变长数组中最接近的 - 选择始终使用的最大缓冲区大小,如果给定的
limit
参数溢出,则会失败
- compile your code as C99 via
-std=c99
or-std=gnu99
- allocate your buffer via
malloc()
- use
alloca()
if available, which is the closest you can come to variable-length arrays with C90 - choose a maximum buffer size which is always used and fail if the given
limit
argument overflows
请注意,即使C99允许使用可变长度数组,但使用静态存储持续时间的整数变量的值作为具有静态存储持续时间的数组的大小仍然是非法的,而与const
限定无关:如果在同一翻译单元中初始化整数变量,虽然没有什么可以从原则上阻止这种情况,但是对于那些定义位于不同翻译单元中的变量,您必须使用具有可见定义的特殊情况变量,并且要么必须禁止暂定定义或需要进行多次编译,因为在解析了整个翻译单元之前,暂时定义的变量的初始化值是未知的.
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.
这篇关于ISO C90禁止使用可变长度数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!