Can someone explain why the following code produces different output for the test4 variable compared to the other 3? I have checked this with gcc version 4.2.1 and 4.5.3 (and others in between).
Maybe I am missing something obvious, but it looks pretty straightforward…
#include <stdio.h>
#include <complex.h>
main()
{
double complex test1, test2, test3, test4;
test1 = 81141117.0;
test2 = 81141117.0 + I * 0;
test3 = 81141117 + I * 0.0;
test4 = 81141117 + I * 0;
printf("%ld + %ld I, %ld + %ld I, ", (long)creal(test1), (long)cimag(test1), (long)creal(test2), (long)cimag(test2));
printf("%ld + %ld I, %ld + %ld I\n", (long)creal(test3), (long)cimag(test3), (long)creal(test4), (long)cimag(test4));
}
Output:
81141117 + 0 I, 81141117 + 0 I
81141117 + 0 I, 81141120 + 0 I
It appears that test4, having integer terms only, is being promoted to a float instead of the declared double, and round-off is coming into play.
I’ve tested GCC 4.7.1 on Mac OS X 10.7.5 (home-built GCC), and also the system provided
/usr/bin/gccand/usr/bin/clang, and they all produce the same result you report.I agree with your analysis that there must be a conversion to
floatinstead ofdoublewhen both terms of the complex number are expressed as integers. The C 2011 standard includes the example:ISO/IEC 9899:2011 §6.7.9 Initialization
This clearly indicates that you should be able to write integer expressions and obtain a valid
double complex(though examples are non-normative). However, it does not address whether the integer value should be converted tofloatbefore being converted todouble, but there’s nowhere else in the language that would do that automatically (obviously, you can force it), so it is unlikely to be the intended interpretation.On the whole, I think this is likely to be a bug that could be reported to the GCC team (and that’s not something I advocate doing lightly). If you run
gcc --help, the output ends with the message:I would extend your example as shown below (or, rather, I did extend your example as shown below):
The output I got was:
As you can see, the last two lines, where there was an explicit
(float)cast or explicit float constants, produce the same results as your problematic line (but the values are legitimate).You might (or might not) want to experiment with the
CMPLX,CMPLXF(and maybeCMPLXL) macros; I’d only add them to the reported example if they produced ‘interesting’ values for some definition of ‘interesting’.Compiler version numbers: