所以我希望在编译时知道结构中数组大小的定义。我也希望这个号码可以作为变量使用,以方便以后使用。我所拥有的是以下内容:
const int BANANA_ARRAY_SIZE = 10;
typedef struct
{
char bananas[BANANA_ARRAY_SIZE];
int some_other_stuff;
} banana_struct;
这个功能很好。但是,如果我将它放在一个包含在多个位置的.h文件中,编译器会抱怨重新定义BANANA_ARRAY_SIZE(这是有道理的)。所以我需要将它声明为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
有什么方法可以实现我想要的(将数组的长度存储在变量中并用于定义struct)?
修改
在回应使用#define
s的建议时,我宁愿不这样做。
我的问题是关于如何将此常量值存储在变量中,还用于设置结构中数组的长度。如果你需要进一步的理由,假设我需要一个带有指向int的指针的函数。无法参考#define。
答案 0 :(得分:7)
在C语言中==
对象不是常量。您不能使用它来声明非VLA数组。您的第一个声明不能用C语言编写,这使得“函数正常”的含义不清楚。
请点击此处了解详情:Shall I prefer constants over defines?
在您的情况下,您只能使用const
或#define
常量。如果您还想创建指向该值的指针,则还必须根据需要在全局或本地声明具有相同值的enum
对象。但是你将无法在非VLA数组声明中使用它。相反,您必须使用const
或#define
常量。 E.g。
enum
答案 1 :(得分:4)
您可以使用枚举或{
'comment': 'Functions'
'match': '^\\s*(function)\\s*(\\w*)'
'captures':
'1':
'name': 'variable.other.newlang'
'2':
'name': 'support.function.any-method.newlang'
}
#define
或
enum {
BANANA_ARRAY_SIZE = 10
};
答案 2 :(得分:0)
您必须使用/
,因此它不是 redifined ,您需要在一个extern
文件中定义一次。
示例强>
header.h
.c
main.c中 1
extern const int BANANA_ARRAY_SIZE;
1 这是出于演示目的,您不必在现实生活中添加原型,您必须关心源代码布局并确保原型与函数匹配定义等
banana.c
void banana(void); /* provide a prototype for `banana()' */
/* A single definition */
const int BANANA_ARRAY_SIZE = 10;
int main(void)
{
banana();
return 0;
}
使用。编译
#include "header.h"
#include <stdio.h>
void banana(void)
{
printf("%d\n", BANANA_ARRAY_SIZE);
}
执行时将打印gcc -Wall -Werror -o banana banana.c main.c
。
但我会推荐一个宏,比如
10
然后你甚至可以在编译时定义它
#define BANANA_ARRAY_SIZE 10
以防止重新定义或根本不包含公共头文件的定义
gcc -DBANANA_ARRAY_SIZE=10 a.c b.c d.c -o executable
答案 3 :(得分:0)
根据C11草案6.6#10,&#34;实现可以接受其他形式的常量表达。&#34;。
尝试使用gcc 4.8.2:
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];
所以这不起作用(如果有的话会让我惊讶)。即使如果 id工作,它也会被实现定义,甚至可能在同一编译器的两个补丁之间发生变化。
有一个明显的原因导致这种情况无法正常工作,特别是如果const具有全局范围:如果编译的模块包含带声明的标头,则编译器无法知道实际的值 常量变量(!)。那么它如何为.bss
部分中的数组保留空间,或者如果给出初始化器(并在.data
部分中分配空间),则能够检查范围?
这需要链接器的干预,并且会对初始化器等产生更大的影响。我非常确定没有编译器会因为给出的原因接受这个。
因此,您必须使用#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_t
。这就是它(以及其他)的用途。