C++ is derived from C, and the authors of the C89 Standard did not want to forbid a compiler, given something like [their example, quoted verbatim]:
int a;
void f( double * b )
{
a = 1;
*b = 2.0;
g(a); // Presumably g is declared as e.g. `void g(int);` somewhere?
}
from generating code that passes g
the value written to a
, rather than having it read a
after the write to *b
and pass g
whatever value was read. Such optimizations are entirely reasonable in cases where an object gets accesses twice, and nothing that a compiler would need to see while processing such accesses would suggest any relationship between the type of the object and any other types which are used between those accesses.
Just as the authors of the Standard saw no need to mandate that implementations be capable of processing any particular nesting of function calls, they saw no need to mandate that compilers expend any particular level of effort recognizing relationships between pointers and lvalues of different types. Given something like:
long get_float_bits( float * b )
{
return *(long*)b;
}
float q;
long test(void)
{
q = 1.0f;
long result = get_float_bits(&q);
q = 2.0f;
}
I don't think of the Committee members could have imagined anyone compiler seriously arguing that because get_float_bits
couldn't possibly access an object of type float
, a quality compiler should omit the first write to q
. Such logic would have been seen as similar to a compiler writer deciding that because the Standard doesn't mandate that implementations support more than two levels of function nesting, quality compilers should optimize programs by omitting any calls to functions that they could prove were nested at least four deep. The reason the Standard doesn't prohibit such conduct isn't that the authors wanted to invite it, but rather because they would have viewed such conduct as sufficiently obviously outrageous that nobody would buy compilers that behaved in such fashion.
Unfortunately, the authors of C89 went out of their way to avoid suggesting that some implementations might be viewed as better than others, and thus avoided mentioning anything that quality implementations should do without being absolutely required to do them, and the authors of gcc have interpreted such avoidance as meaning that any code which relied upon anything not mandated by the Standard should be viewed as "broken".