【发布时间】:2020-11-16 12:16:06
【问题描述】:
在 libfixmath 中有the following macro magic:
#define F16C(i, m) \
( (fix16_t) \
( \
(( #i[0] ) == '-') \
? -FIXMATH_COMBINE_I_M((unsigned)( ( (i) * -1) ), m) \
: FIXMATH_COMBINE_I_M((unsigned)i, m) \
) \
)
这样用了几十次:
F16C(3,1415)
初始化各种事物,从结构到数组和临时对象。
在 ARMCC 中运行良好。但是我正在迁移到 ARM GCC,它给了我以下错误,但不是在所有实例上,主要是在进行 const 结构初始化时。
error: initializer element is not constant
这与使用非常数作为初始化器有关。这是可以理解的。
但是这个宏被赋予了两个整数字面量。没有比这更稳定的了!
我是否遗漏了什么,或者是否有我不知道的 GCC 扩展来完成这项工作?
更新:macro called by this 中有一个 sizeof(#token)。
注意:与 ARMCC 相比,GCC 可以正确解析 F16() 宏并且不会创建 fplib 调用。只是提醒那些将来发现自己遇到此问题的人。
【问题讨论】:
-
您为什么认为使用
?运算符会产生适合用作初始化程序的常量表达式? -
根据godbolt,它works in gcc 8.2但在7.3中失败。
-
@AndrewHenle:因为 C 2018 6.6 6 允许整数常量表达式包含运算符,包括
? :。 -
宏将
i转换为字符串(#i),然后尝试取其第一个字符(#i[0]中的[0])。 C 2018 6.6 6 中规定了编译器需要接受的整型常量表达式,不包括使用字符串作为操作数。编译器可能会接受这一点(因为 6.6 10 允许,但不需要它),这可以解释为什么 ARMCC 接受它而旧版本的 GCC 不接受。