If the implementation is in accordance with Appendix G and implements the _Imaginary types, then the expression
b = 0.0 + (__extension__ -0.0iF)
evaluated as (double)0.0 + (double _Imaginary)(-0.0i) in accordance with the rules in G.5.2 and gives 0.0 - 0.0i .
If the implementation does not provide the _Imaginary type (which is permitted) or otherwise does not comply with Appendix G (also permitted), then this expression is usually evaluated as:
(double _Complex)(0.0 + 0.0i) + (double _complex)(0.0 - 0.0i) = (double _Complex)((0.0 + 0.0) + (0.0 - 0.0)i)
Since 0.0 - 0.0 is a positive zero in standard IEEE-754 rounding, the sign is lost.
The moral of the story: if you care about the sign of zero, do not use arithmetic in complex initializers. Since you are using GCC, you can do this instead:
__real__ c = 0.0f; __imag__ c = -0.0f;
In my experience, this works at least on gcc-4.0 or so (maybe further).
As for why the behavior was caused by -std=c99 , my best guess is this: the GCC version that you use implements the _Imaginary type, which does not fully match C99; when you specify -std=c99 , _Imaginary support is disabled, and you return to the _Complex matching implementation, which works as described above. However, this is only an assumption; if you are really interested, I would advise you to file a mistake and see what the people accompany you. In fact, I would advise you to file an error anyway. Always log an error .
Stephen canon
source share