0

我知道有一些与此错误相关的问题:
thread1thread2thread3thread4,...

不同的是,我不使用变量来定义大小,而是使用宏。

这是我所做的:

#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根据这些我定义了二维数组 ( ) 的大小 ( TOTAL_A, ) ,以及该数组中的单元格总数 ( )。然后我从总数中提取一部分 ( ) 来定义我想要创建的另一个数组的大小 ( )。TOTAL_Btoto_t totoTOTALSIZE_1foo_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;
}
4

1 回答 1

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 标准规则的所有信息。

于 2019-12-13T08:22:37.363 回答