C 基于文件间常量int的结构成员数组大小
所以我想在编译时定义结构中数组的大小。我也希望这个数字可以作为一个变量,以便以后使用。我所拥有的是:C 基于文件间常量int的结构成员数组大小,c,arrays,struct,C,Arrays,Struct,所以我想在编译时定义结构中数组的大小。我也希望这个数字可以作为一个变量,以便以后使用。我所拥有的是: const int BANANA_ARRAY_SIZE = 10; typedef struct { char bananas[BANANA_ARRAY_SIZE]; int some_other_stuff; } banana_struct; 这个功能很好。然而,如果我把它放在一个包含在多个地方的.h文件中,编译器会抱怨重新定义了香蕉数组大小(这很有意义)。所以我需要将它声明为一个
const int BANANA_ARRAY_SIZE = 10;
typedef struct
{
char bananas[BANANA_ARRAY_SIZE];
int some_other_stuff;
} banana_struct;
这个功能很好。然而,如果我把它放在一个包含在多个地方的.h文件中,编译器会抱怨重新定义了香蕉数组大小(这很有意义)。所以我需要将它声明为一个extern,以便多个编译单元可以了解它
所以,我现在有
extern const int BANANA_ARRAY_SIZE;
typedef struct
{
//.. same as before
} banana_struct;
在我的一个实现文件中
const int BANANA_ARRAY_SIZE = 10;
但是现在编译器不再让我定义结构,因为我抱怨
fields must have a constant size: variable length array in structure
是否有任何方法可以实现我想要的(将数组的长度存储在变量中并用于定义结构)
编辑:
作为对使用#define
s的建议的回应,我宁愿不使用
我的问题是如何将这个常量值存储在变量中,并用于设置结构中数组的长度。如果您需要进一步的对正,假设我需要一个指向int的指针的函数。不能引用#define。您必须使用
extern
,因此它不会被重新定义,您需要在单个.c
文件中定义一次
示例
1这是为了演示的目的,您不仅要在现实生活中添加原型,还必须关注源代码布局,并确保原型与函数定义匹配,等等
10
但我会推荐一个宏,比如
#定义香蕉数组大小10
然后您甚至可以在编译时定义它,如
gcc-DBANANA\u数组大小=10a.c b.c d.c-o可执行文件
为了防止重新定义或根本没有定义,公共头文件将包含
\ifndef香蕉数组\u大小
#定义香蕉\u数组\u大小10
#恩迪夫
您可以使用枚举或定义
enum {
BANANA_ARRAY_SIZE = 10
};
或
在C语言中,const对象不是常量。不能使用它来声明非VLA数组。您的第一个声明不能用C语言编译,这使您不清楚“函数良好”是什么意思 有关更多详细信息,请参见此处: 在您的情况下,您只能使用
#define
或enum
常量。如果还希望创建指向该值的指针,则必须另外声明一个具有相同值的const
对象,可以根据需要全局或局部声明。但您将无法在非VLA数组声明中使用它。相反,您必须使用#define
或enum
常量。例如
// In .h file
#define BANANA_ARRAY_SIZE 10
extern const int BANANA_ARRAY_SIZE_OBJ;
// In .c file
const int BANANA_ARRAY_SIZE_OBJ = BANANA_ARRAY_SIZE;
根据C11草案6.6#10,“实现可以接受其他形式的常量表达式。”
在gcc 4.8.2中尝试过:
static const size_t arr_size = 10; // static does not change anything
static int arr[arr_size]; // dito
因此,这是行不通的(如果有,我会大吃一惊)。即使id有效,它也将由实现定义,甚至可能在同一编译器的两个修补程序之间发生更改 这种方法不起作用有一个明确的原因,特别是当const具有全局作用域时:如果编译的模块包含带有声明的头,编译器就无法知道该常量变量(!)的实际值。那么它如何在
.bss
节中为数组保留空间,或者如果给定了初始值设定项,它如何能够检查范围(以及.data
节中的alloc空间)?
这将需要链接器的干预,并且会对初始值设定者产生更大的影响,等等。我很确定没有编译器会因为给出的原因接受这一点
因此,您必须使用
#define
:
"array.h":
#define MAX_ARR_LEN 10
extern const size_t max_arr_len;
"array.c":
const size_t max_arr_len = 10;
注意:对数组边界使用
size\u t
。这就是它的用途(除其他外)。这与OP有什么不同?他明确提到他在头文件中使用了extern
。问题是在头文件中定义结构,同时在.cI中保留BANANA\u ARRAY\u SIZE
定义。我知道使用extern。我甚至在我的问题中也提到了这一点。问题是“为什么我不能使用extern const值来定义数组的长度?”。另外,请参见我的编辑:使用#defines@Phildo我完全错过了这个问题,因为它看起来简单多了,但这是一个很好的问题,我还没有答案。很抱歉,gcc编译了我刚刚写的一个例子,所以无法重现您的问题,您使用的是哪个编译器,哪个版本?在C语言中,您不能用gcc按照他的要求执行操作。即使编译器会接受这一点,它充其量也只是实现定义的。显然,您只能在C中的局部范围内进行这种类型的初始化,而不能在您正在尝试的全局范围内进行初始化。在同一篇帖子中:请阅读我的最新评论,这是关于我答案的最后一条评论。在我的gcc-5.1.0中没有这种情况。#定义香蕉数组大小10
char BANANA[BANANA数组大小];常量大小\u t长度=香蕉数组大小
@Ryker:that在本地范围内也不起作用,因为VLA必须在块的顶层,而不是在结构内部(不过,有一种方法可以使用flex数组成员,但这会包含一些繁重的内容。我想知道gcc是否在这方面不符合规范,因为:const int LEN=12;char my_array[LEN];int main(){my_array[0]='a';return 0;}编译得很好…不管怎样,我猜基本上c中的“这不能根据规范来完成”。谢谢你提供的信息!@Phildo:-std=c99
或c11
?这不是“规范”“Phildo:这绝对是不符合任何版本的C。你确定你在C模式而不是C++模式编译吗?C++中的代码是合法的。@奥拉夫在我之前的注释中编译了代码->代码> GCC—STD= C11主。C o o A.OUT < /Cord>作品。
#define BANANA_ARRAY_SIZE 10
// In .h file
#define BANANA_ARRAY_SIZE 10
extern const int BANANA_ARRAY_SIZE_OBJ;
// In .c file
const int BANANA_ARRAY_SIZE_OBJ = BANANA_ARRAY_SIZE;
static const size_t arr_size = 10; // static does not change anything
static int arr[arr_size]; // dito
gcc -std=gnu11 -Wall test.c
test.c:6:12: error: variably modified ‘arr’ at file scope
static int arr[arr_size];
"array.h":
#define MAX_ARR_LEN 10
extern const size_t max_arr_len;
"array.c":
const size_t max_arr_len = 10;