gcc 里定义数组时如果长度是浮点运算结果会报 variably modified 'xxx' at file scope 警告,有没有办法能消除警告? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wudicgi
V2EX    C

gcc 里定义数组时如果长度是浮点运算结果会报 variably modified 'xxx' at file scope 警告,有没有办法能消除警告?

  •  
  •   wudicgi 2023 年 4 月 6 日 2482 次点击
    这是一个创建于 1023 天前的主题,其中的信息可能已经有所发展或是发生改变。

    像这样一段代码

    #include <stdio.h> // 100.0 / 27.0 = 3.7037 -> (int)3 #define BUFFER_SIZE ((int)((double)100 / (double)27)) // sizeof(_buffer) = 3 unsigned char _buffer[BUFFER_SIZE]; int main(void) { printf("Hello World, sizeof(buffer) = %u\n", (unsigned int)sizeof(_buffer)); return 0; } 

    MSVC 编译器不会报任何警告, clang 通过加 -Wno-gnu-folding-constant 参数也能消除警告。

    gcc 会在 _buffer 数组定义这一行报 warning: variably modified '_buffer' at file scope, 始终没找到啥办法能让它不报这个警告,只能把表达式改成整数运算形式的。

    11 条回复    2023-04-07 11:23:26 +08:00
    wudicgi
        1
    wudicgi  
    OP
       2023 年 4 月 6 日
    以下是在在线编译器中编译的结果:

    gcc 12.2 // 尚未找到解决办法
    https://godbolt.org/z/a7sG88ooa

    <source>:7:1: error: variably modified '_buffer' at file scope [-Werror]
    7 | unsigned char _buffer[BUFFER_SIZE];
    | ^~~~~~~~

    clang 16.0.0 // 添加 -Wno-gnu-folding-constant 编译参数后警告可被去除
    https://godbolt.org/z/GWEoWMsvv

    <source>:7:15: error: variable length array folded to constant array as an extension [-Werror,-Wgnu-folding-constant]
    unsigned char _buffer[BUFFER_SIZE];
    ^

    msvc 19.33 // 没有任何警告或错误
    https://godbolt.org/z/nME5W553d
    ysc3839
        2
    ysc3839  
       2023 年 4 月 6 日 via Android
    怀疑是被当成 VLA ?尝试禁用 VLA ?
    如果是 C++的话可以考虑用 std::integral_constant 包一层
    lakehylia
        3
    lakehylia  
       2023 年 4 月 6 日
    你这个为啥还要转成 double 再转 int 啊,直接 #define BUFFER_SIZE (100/27) 不就行了?或者 static const int BUFFER_SIZE = 100/27;
    整型的除法结果就是商啊。
    wudicgi
        4
    wudicgi  
    OP
       2023 年 4 月 6 日
    @ysc3839 这种情况应该也是被当成 VLA 了,我改成指定 -std=c11 -Werror=vla 参数后,提示信息变为:

    <source>:7:1: warning: variably modified '_buffer' at file scope
    7 | unsigned char _buffer[BUFFER_SIZE];
    | ^~~~~~~~
    <source>:7:1: error: ISO C90 forbids array '_buffer' whose size cannot be evaluated [-Werror=vla]
    cc1: some warnings being treated as errors

    不过查到结果是 gcc 里不能禁用 VLA 支持。
    wudicgi
        5
    wudicgi  
    OP
       2023 年 4 月 6 日
    @lakehylia 这里为了方便看到核心问题,就放了个最简单的表达式。
    实际的表达式有好几层括号,还有 (int)(x + 0.5) 这样实现四舍五入的部分,改成整数运算的表达式看着就会非常不直观。
    lakehylia
        6
    lakehylia  
       2023 年 4 月 6 日
    我在 mac 上面用 clang 和 gcc 没有任何警告啊,用 cpp 文件编译的
    wudicgi
        7
    wudicgi  
    OP
       2023 年 4 月 6 日
    为了防止被认为可能是 X-Y 问题,我再贴一下原始问题。

    如果可以正常用浮点数运算,再转成整数作为数组大小,那么我可以使用:
    #define CONFIG_SLICE_COUNT_PER_SECOND ((double)((double)11025 / (double)63))
    #define HALF_HANN_200MS_LENGTH ((int)(((CONFIG_SLICE_COUNT_PER_SECOND * 0.2) / 2) + 0.5))

    如果为了避开这个警告信息,全部使用整数运算,那么我需要这样写:
    #define CONFIG_SLICE_COUNT_PER_SECOND (11025 / 63) // 恰好能被整除
    #define HALF_HANN_200MS_LENGTH ((((CONFIG_SLICE_COUNT_PER_SECOND * 2) / 10) + 1) / 2)

    就非常不直观,虽然对于 200ms -> 0.2s, +0.5 实现四舍五入这些我可以再写一些宏把它包装起来,
    但对于 11025 / 63 这种地方,如果不是恰好能被整除的话就还是有额外的问题,不处理会损失一些精度。
    cnbatch
        8
    cnbatch  
       2023 年 4 月 6 日
    @lakehylia cpp 后缀改成 c (也就是使用纯 C ),就能复现了
    wudicgi
        9
    wudicgi  
    OP
       2023 年 4 月 6 日
    @lakehylia 我开始进 godbolt.org 的时候,默认语言是 C++, 编译器选择 gcc 确实没有这个警告,把语言换成 C 之后就有了。

    现在默认编译时是调用的 gcc 不是 g++, 能否改成用 g++ 编译我再看看。
    因为现在问题主要在发生在编译 ESP32 固件时,它的 SDK 默认调用的是 xtensa-esp32-elf-gcc.exe
    ysc3839
        10
    ysc3839  
       2023 年 4 月 6 日 via Android
    @wudicgi 不确定 ESP32 是否支持 C++,但是 Arduino 是支持的。建议改用 C++。
    TripleLens
        11
    TripleLens  
       2023 年 4 月 7 日
    试了一下用枚举常量就没有警告,这里行为可能有点不一致
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     924 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 20:37 PVG 04:37 LAX 12:37 JFK 15:37
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86