In many discussions about undefined behavior (UB), the point of view has been put forward that in the mere presence in a program of any construct that has UB in a p
In the dialect processed by gcc with full optimizations enabled, if a program contains two constructs which would behave identically in cases where both are defined, reliable program operation requires that any code that would switch among them only be executed in cases where both are defined. For example, when optimizations are enabled, both ARM gcc 9.2.1 and x86-64 gcc 10.1 will process the following source:
#include
#if LONG_MAX == 0x7FFFFFFF
typedef int longish;
#else
typedef long long longish;
#endif
long test(long *x, long *y)
{
if (*x)
{
if (x==y)
*y = 1;
else
*(longish*)y = 1;
}
return *x;
}
into machine code that will test if x
and y
are equal, set *x
to 1 if they are and *y
to 1 if they aren't, but return the previous value of *x
in either case. For purpose of determining whether anything might affect *x
, gcc decides that both branches of the if
are equivalent, and thus only evaluates the "false" branch. Since that can't affect *x
, it concludes that the if
as a whole can't either. That determination is unswayed by its observation that on the true branch, the write to *y
can be replaced with a write to *x
.