【问题标题】:"Variably modified 'variable_name' at file scope" with size defined in macro [duplicate]“在文件范围内可变地修改了'variable_name'”,在宏中定义了大小[重复]
【发布时间】:2019-12-13 08:11:00
【问题描述】:

我知道有一些与此错误相关的问题:
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_ASIZE_BSCALE)。我根据这些定义了二维数组 (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;
}

【问题讨论】:

  • 为什么要替换我为您制作的最小示例,并通过代码描述完美重现您的问题??

标签: c arrays gcc macros size


【解决方案1】:

这里的问题是 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;

This answer 将为您提供有关 C 标准规则的所有信息。

【讨论】:

  • 我不能改变SCALE 的值,因为我用它来做一些其他的计算。它将使代码的其余部分复杂化
  • @Phantom:C 标准要求在此上下文中为数组大小使用 整数常量表达式。它可能不包含浮点运算。如果您无法更改 SCALE,则必须使用其他方式来管理未在文件范围内或在大小使用 SCALE 的结构中声明数组的数据。
  • @Phantom Simple:你不能做你想做的事。看看This question
  • @LPs 是的,它回答了我的问题。但我可以做我想做的事。 :p 根据您的建议,我只需添加另一个宏 #define SCALE_2 (SCALE/100)。然后使用这个宏。谢谢你的回答
  • @LPs 有趣的是它编译了with clang, but not with gcc
猜你喜欢
  • 2013-02-02
  • 2014-03-07
  • 1970-01-01
  • 2019-11-16
  • 2013-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-05
相关资源
最近更新 更多