是否可以在 C 常量表达式中进行联合类型双关?

Is it possible to do union type punning in a C constant expression?

我有一个函数可以使用联合将一系列字节转换为浮点数。我用它来精确表示一些难写的数字,比如NaN和Infinity。

float i2f(uint32_t i)
{
    union { uint32_t i; float f; } u;
    u.i = i;
    return u.f;
}

我遇到的问题是我无法在需要常量表达式的地方使用此函数,例如静态初始化程序:

// error: initializer element is not constant
float fs[2] = { i2f(0xffc00000), i2f(0x7f800000) };

是否有另一种方法可以实现同样的效果,使得生成的表达式作为常量表达式有效?

到目前为止,我发现将 NaN 表示为常量的唯一方法是使用不可移植的 __builtin_nan 扩展。如果可能的话,我更喜欢在 C 标准范围内工作的东西。

C 标准在严格符合的代码中没有提供任何可以为此产生 整数常量表达式 的特性。

我们最接近的可能是创建一个复合文字并获取其中的一个成员:

(union { uint32_t u; float f; }) { 0xffc00000} .f

但是,这不是 C 标准定义的常量表达式,除了 C 2018 6.6 10 说“实现可以接受其他形式的常量表达式。”

可以满足您的目的的是简单地定义包含所需值的联合:

union { uint32_t u; float f; } fs[2] = { { 0xffc00000} , { 0x7f800000 } };

之后您将使用他们的成员,fs[0].ffs[1].f,等等。