Possible Duplicate:
can we give size of static array a variable可能重复:我们可以给静态数组的大小一个变量
I am defining an array in one of the child files as follows.
我在其中一个子文件中定义一个数组,如下所示。
static int arr[siz];
Here siz
is a global variable available to the child file. But the gcc compiler produces the following error :
这里siz是子文件可用的全局变量。但是gcc编译器会产生以下错误:
<filename>: <line_num> : error : storage size of ‘arr’ isn’t constant
Why can't I define a static
array of variable size ?
为什么我不能定义可变大小的静态数组?
EDIT : This seems to be a problem only for static int
type. If I change the variable type of arr
from static int
to int
, the error goes away, even though the size of array is still dependent on a variable siz
.
编辑:这似乎只是静态int类型的问题。如果我将arr的变量类型从static int更改为int,则即使数组的大小仍依赖于变量siz,错误也会消失。
4 个解决方案
#1
10
Since the size of the array you declare is not constant, what you have is an Variable Length Array(VLA). VLA are allowed by the c99 standard but there are some limitations associated with it. You cannot have an variable length array with static
or extern
storage class specifier.
由于您声明的数组的大小不是常量,因此您拥有的是可变长度数组(VLA)。 c99标准允许VLA,但存在一些与之相关的限制。您不能拥有带有静态或外部存储类说明符的可变长度数组。
You have an VLA with static
storage specification and it is not allowed by the C99 Standard.
您有一个具有静态存储规范的VLA,C99标准不允许这样做。
Reference:
参考:
c99 Standard: 6.7.5.2/8
c99标准:6.7.5.2/8
EXAMPLE 4 All declarations of variably modified (VM) types have to be at either block scope or function prototype scope. Array objects declared with the static or extern storage class specifier cannot have a variable length array (VLA) type. However, an object declared with the static storage class specifier can have a VM type (that is, a pointer to a VLA type). Finally, all identifiers declared with a VM type have to be ordinary identifiers and cannot, therefore, be members of structures or unions.
示例4可变修改(VM)类型的所有声明必须处于块范围或函数原型范围。使用static或extern存储类指定器声明的数组对象不能具有可变长度数组(VLA)类型。但是,使用静态存储类规范声明的对象可以具有VM类型(即指向VLA类型的指针)。最后,所有使用VM类型声明的标识符必须是普通标识符,因此不能是结构或联合的成员。
So if you want a dynamic size array with static
storage specifier you will have to use a dynamic array allocated on heap.
因此,如果您需要具有静态存储说明符的动态大小数组,则必须使用在堆上分配的动态数组。
#define MAX_SIZE 256
static int* gArr;
gArr = malloc(MAX_SIZE * sizeof(int));
EDIT:
To answer your updated question:
When you remove the static
keyword from the declaration, the storage specifier of the declared array changes from static
to global, note the standard quote above, it clearly mentions the restriction that VLAs are not allowed with static
and extern
storage specification. Clearly, you are allowed to have an VLA with global storage specification, which is what you have once you remove the static
keyword.
编辑:回答你更新的问题:当你从声明中删除static关键字时,声明的数组的存储说明符从静态更改为全局,请注意上面的标准引用,它清楚地提到静态和不允许使用VLA的限制。外部存储规范。显然,您可以拥有具有全局存储规范的VLA,这是您删除static关键字后的内容。
#2
2
You are allocating the array at compile-time, so the compiler has to know the array's size in advance. You have to declare siz
as a constant expression before you declare arr
, for instance:
您是在编译时分配数组,因此编译器必须事先知道数组的大小。在声明arr之前,必须将siz声明为常量表达式,例如:
#define siz 5
or
要么
enum ESizes
{
siz = 5
};
Alternatively, if you need to determine its size in run-time, you can allocate it on the heap by using malloc
:
或者,如果需要在运行时确定其大小,可以使用malloc在堆上分配它:
static int* arr;
arr = (int*)malloc(siz * sizeof(int))
EDIT: as eddieantonio has mentioned, my answer is valid for C89. In C99 it is allowed to declare arrays of variable size.
编辑:正如eddieantonio所说,我的答案对C89有效。在C99中,允许声明可变大小的数组。
#3
1
You can't define any array of variable size. That's because arr[siz]
makes the compiler (!) allocate memory for your array (well, the compiler creates a program, that .., but let's not stray into details). However, variables can be changed at runtime (!) which means the compiler has no chance of knowing how much memory to allocate.
您无法定义任何可变大小的数组。那是因为arr [siz]使得编译器(!)为你的数组分配内存(好吧,编译器创建一个程序,那......,但不要偏离细节)。但是,变量可以在运行时更改(!),这意味着编译器无法知道要分配多少内存。
What you can do is
你能做的是
static int* arr;
arr = (int*) calloc(siz,sizeof(int))
These lines result in a program that allocates memory at runtime, therefore it's exact size may be defined at runtime as well.
这些行导致程序在运行时分配内存,因此它的确切大小也可以在运行时定义。
#4
0
You cannot declare a static
array of variable size because its space is allocated in the Data Segment (or bss segment in case of an uninitialized variable). Hence the compiler needs to know the size at the compile time and will complain if the size is not a constant.
您不能声明可变大小的静态数组,因为它的空间是在数据段中分配的(如果是未初始化的变量,则为bss段)。因此编译器需要在编译时知道大小,并且如果大小不是常量则会抱怨。
The underlying reason for this is the Data Segment size contributes to the size of the executable being generated, which obviously is created at compile time, and hence has to be fixed.
其根本原因是数据段大小有助于生成的可执行文件的大小,这显然是在编译时创建的,因此必须修复。
#1
10
Since the size of the array you declare is not constant, what you have is an Variable Length Array(VLA). VLA are allowed by the c99 standard but there are some limitations associated with it. You cannot have an variable length array with static
or extern
storage class specifier.
由于您声明的数组的大小不是常量,因此您拥有的是可变长度数组(VLA)。 c99标准允许VLA,但存在一些与之相关的限制。您不能拥有带有静态或外部存储类说明符的可变长度数组。
You have an VLA with static
storage specification and it is not allowed by the C99 Standard.
您有一个具有静态存储规范的VLA,C99标准不允许这样做。
Reference:
参考:
c99 Standard: 6.7.5.2/8
c99标准:6.7.5.2/8
EXAMPLE 4 All declarations of variably modified (VM) types have to be at either block scope or function prototype scope. Array objects declared with the static or extern storage class specifier cannot have a variable length array (VLA) type. However, an object declared with the static storage class specifier can have a VM type (that is, a pointer to a VLA type). Finally, all identifiers declared with a VM type have to be ordinary identifiers and cannot, therefore, be members of structures or unions.
示例4可变修改(VM)类型的所有声明必须处于块范围或函数原型范围。使用static或extern存储类指定器声明的数组对象不能具有可变长度数组(VLA)类型。但是,使用静态存储类规范声明的对象可以具有VM类型(即指向VLA类型的指针)。最后,所有使用VM类型声明的标识符必须是普通标识符,因此不能是结构或联合的成员。
So if you want a dynamic size array with static
storage specifier you will have to use a dynamic array allocated on heap.
因此,如果您需要具有静态存储说明符的动态大小数组,则必须使用在堆上分配的动态数组。
#define MAX_SIZE 256
static int* gArr;
gArr = malloc(MAX_SIZE * sizeof(int));
EDIT:
To answer your updated question:
When you remove the static
keyword from the declaration, the storage specifier of the declared array changes from static
to global, note the standard quote above, it clearly mentions the restriction that VLAs are not allowed with static
and extern
storage specification. Clearly, you are allowed to have an VLA with global storage specification, which is what you have once you remove the static
keyword.
编辑:回答你更新的问题:当你从声明中删除static关键字时,声明的数组的存储说明符从静态更改为全局,请注意上面的标准引用,它清楚地提到静态和不允许使用VLA的限制。外部存储规范。显然,您可以拥有具有全局存储规范的VLA,这是您删除static关键字后的内容。
#2
2
You are allocating the array at compile-time, so the compiler has to know the array's size in advance. You have to declare siz
as a constant expression before you declare arr
, for instance:
您是在编译时分配数组,因此编译器必须事先知道数组的大小。在声明arr之前,必须将siz声明为常量表达式,例如:
#define siz 5
or
要么
enum ESizes
{
siz = 5
};
Alternatively, if you need to determine its size in run-time, you can allocate it on the heap by using malloc
:
或者,如果需要在运行时确定其大小,可以使用malloc在堆上分配它:
static int* arr;
arr = (int*)malloc(siz * sizeof(int))
EDIT: as eddieantonio has mentioned, my answer is valid for C89. In C99 it is allowed to declare arrays of variable size.
编辑:正如eddieantonio所说,我的答案对C89有效。在C99中,允许声明可变大小的数组。
#3
1
You can't define any array of variable size. That's because arr[siz]
makes the compiler (!) allocate memory for your array (well, the compiler creates a program, that .., but let's not stray into details). However, variables can be changed at runtime (!) which means the compiler has no chance of knowing how much memory to allocate.
您无法定义任何可变大小的数组。那是因为arr [siz]使得编译器(!)为你的数组分配内存(好吧,编译器创建一个程序,那......,但不要偏离细节)。但是,变量可以在运行时更改(!),这意味着编译器无法知道要分配多少内存。
What you can do is
你能做的是
static int* arr;
arr = (int*) calloc(siz,sizeof(int))
These lines result in a program that allocates memory at runtime, therefore it's exact size may be defined at runtime as well.
这些行导致程序在运行时分配内存,因此它的确切大小也可以在运行时定义。
#4
0
You cannot declare a static
array of variable size because its space is allocated in the Data Segment (or bss segment in case of an uninitialized variable). Hence the compiler needs to know the size at the compile time and will complain if the size is not a constant.
您不能声明可变大小的静态数组,因为它的空间是在数据段中分配的(如果是未初始化的变量,则为bss段)。因此编译器需要在编译时知道大小,并且如果大小不是常量则会抱怨。
The underlying reason for this is the Data Segment size contributes to the size of the executable being generated, which obviously is created at compile time, and hence has to be fixed.
其根本原因是数据段大小有助于生成的可执行文件的大小,这显然是在编译时创建的,因此必须修复。