Consider
int main() {
double d = 1.0e+308;
std::cout << (d*d)/1.0e+308;
}
compiled with g++ version 4.8.5 and the two compiler options -std=c++11 and -mfpmath=387 on a Linux CentOS system (more precisely, Linux 3.10.0-693.21.1.el7.x86_64 with Intel Xeon X5690 CPUs). As expected, this outputs the value 1e+308 because the multiplication d*d is evaluated in 80-bit extended precision and thus no overflow occurs (FLT_EVAL_METHOD returns 2 with these compiler settings). Now consider:
int main() {
double d = 1.0e+308;
double e;
e = d*d;
e = e/1.0e+308;
std::cout << e;
}
This outputs inf - again as expected - since d*d is assigned to the double parameter e and in my understanding of the ISO/IEC 14882:2011 standard Sec. 5, 11, footnote 60, the value of e must be (or at least must behave as) a true double value, i.e. must be inf when used subsequently. However, and this is the point, when I add -O1 to the compiler options, then the output of the program is 1e+308. This violates - in my mind - the requirement that assignments (and casts) "perform their specific conversions" - see the passage in the c++11-standard document mentioned above. Did I misinterpret something here or is gcc not standard compliant (in this regard) when optimization level O1 (or higher) is used?