With the following code,
#define REINT(T, X) (union {__typeof__(X) x; T t;}){X}.t
int f2i(float x) {
return REINT(int, x);
}
float i2f(int x) {
return REINT(float, x);
}
float f2i2f(float x) {
return REINT(float, REINT(int, x));
}
Clang complains about f2i2f that an "initializer element is not a compile-time constant". This seems odd because compound literals "have automatic storage duration associated with
the enclosing block" (6.5.2.5p5), and the elements in the initializer list for such objects don't have to be compile-time constants.
In the comments under the question, it was mentioned that this is a known bug, and "it is quite an old bug still not fixed". So until it's fixed, you'll have to work around it.
The simplest code I could find that triggers the bug is
The bug is triggered when:
__typeof__structor aunionWhen the
REINTmacro is used in thef2iandi2ffunctions, it doesn't trigger the bug because argumentXis not a compound literal.Xin those functions is a variable with a primitive type.But in the
f2i2ffunction, the argumentXpassed to the outer invocation ofREINTcontains a compound literal. And that compound literal is part of the argument to a__typeof__that is used in the definition of the outerunion.So the workaround is to avoid nesting the
REINTmacro. For example,f2i2fcan be implemented as follows: