"Variably modified 'variable_name' at file scope" 大小在宏中定义
"Variably modified 'variable_name' at file scope" with size defined in macro
我知道有一些与此错误相关的问题:
thread1, thread2, thread3, thread4,...
不同的是,我没有使用变量来定义大小,而是使用宏。
我是这样做的:
#define SIZE_A 250 // Real world value
#define SIZE_B 80 // Real world value
#define SCALE 0.25 // Real world value
#define TOTAL_A (uint16_t)(SIZE_A/SCALE)
#define TOTAL_B (uint16_t)(SIZE_B/SCALE)
#define TOTAL TOTAL_A*TOTAL_B
#define SIZE_1 (uint16_t)(TOTAL*0.3)
#define SIZE_2 4000
typedef struct {
toto_t toto[TOTAL_A][TOTAL_B];
foo_t foo[SIZE_1][SIZE_2];
} bar_t;
如您所见,我有三个代表真实事物的宏(SIZE_A
、SIZE_B
、SCALE
)。我从中定义了二维数组 (toto_t toto
) 的大小 (TOTAL_A
、TOTAL_B
),以及该数组中的单元格总数 (TOTAL
)。然后我从总数中取一部分 (SIZE_1
) 来定义我要创建的另一个数组的大小 (foo_t foo
)。
这样 gcc 会抛出错误:Variably modified 'foo' at file scope
。所以,我查看了预处理器输出:
typedef struct {
toto_t toto[(uint16_t)(250/0.25)][(uint16_t)(80/0.25)];
foo_t foo[(uint16_t)((uint16_t)(250/0.25)*(uint16_t)(80/0.25)*0.3)][4000];
} bar_t;
如我们所见,预处理器运行良好。所有宏都替换为文字值。所以数组大小只有常数值。
我的问题
为什么 gcc 不能计算数组的大小?是否有强制它进行计算的选项?
我用这个选项编译 -O3 -Wall -Wextra -Werror
。
测试:
创建一个test.h
并放入我发布的代码并在开头添加typedef uint16_t toto_t; typedef uint16_t foo_t;
。并创建一个 test.c
文件:
#include <stdio.h>
#include <inttypes.h>
#include "test.h"
int main() {
printf("hello world\n");
return 0;
}
这里的问题是SCALE的浮动值。
您可以使用定点值来避免它:
#define SIZE_A 250 // Real world value
#define SIZE_B 80 // Real world value
#define SCALE 25 // Real world value
#define TOTAL_A (SIZE_A*100/SCALE)
#define TOTAL_B (SIZE_B*100/SCALE)
#define TOTAL TOTAL_A*TOTAL_B
#define SIZE_1 (TOTAL*3/10)
#define SIZE_2 4000
typedef struct {
toto_t toto[TOTAL_A][TOTAL_B];
foo_t foo[SIZE_1][SIZE_2];
} bar_t;
将为您提供有关 C 标准规则的所有信息。
我知道有一些与此错误相关的问题:
thread1, thread2, thread3, thread4,...
不同的是,我没有使用变量来定义大小,而是使用宏。
我是这样做的:
#define SIZE_A 250 // Real world value
#define SIZE_B 80 // Real world value
#define SCALE 0.25 // Real world value
#define TOTAL_A (uint16_t)(SIZE_A/SCALE)
#define TOTAL_B (uint16_t)(SIZE_B/SCALE)
#define TOTAL TOTAL_A*TOTAL_B
#define SIZE_1 (uint16_t)(TOTAL*0.3)
#define SIZE_2 4000
typedef struct {
toto_t toto[TOTAL_A][TOTAL_B];
foo_t foo[SIZE_1][SIZE_2];
} bar_t;
如您所见,我有三个代表真实事物的宏(SIZE_A
、SIZE_B
、SCALE
)。我从中定义了二维数组 (toto_t toto
) 的大小 (TOTAL_A
、TOTAL_B
),以及该数组中的单元格总数 (TOTAL
)。然后我从总数中取一部分 (SIZE_1
) 来定义我要创建的另一个数组的大小 (foo_t foo
)。
这样 gcc 会抛出错误:Variably modified 'foo' at file scope
。所以,我查看了预处理器输出:
typedef struct {
toto_t toto[(uint16_t)(250/0.25)][(uint16_t)(80/0.25)];
foo_t foo[(uint16_t)((uint16_t)(250/0.25)*(uint16_t)(80/0.25)*0.3)][4000];
} bar_t;
如我们所见,预处理器运行良好。所有宏都替换为文字值。所以数组大小只有常数值。
我的问题
为什么 gcc 不能计算数组的大小?是否有强制它进行计算的选项?
我用这个选项编译 -O3 -Wall -Wextra -Werror
。
测试:
创建一个test.h
并放入我发布的代码并在开头添加typedef uint16_t toto_t; typedef uint16_t foo_t;
。并创建一个 test.c
文件:
#include <stdio.h>
#include <inttypes.h>
#include "test.h"
int main() {
printf("hello world\n");
return 0;
}
这里的问题是SCALE的浮动值。
您可以使用定点值来避免它:
#define SIZE_A 250 // Real world value
#define SIZE_B 80 // Real world value
#define SCALE 25 // Real world value
#define TOTAL_A (SIZE_A*100/SCALE)
#define TOTAL_B (SIZE_B*100/SCALE)
#define TOTAL TOTAL_A*TOTAL_B
#define SIZE_1 (TOTAL*3/10)
#define SIZE_2 4000
typedef struct {
toto_t toto[TOTAL_A][TOTAL_B];
foo_t foo[SIZE_1][SIZE_2];
} bar_t;