Optimisations and undefined behaviour

Martin Sebor msebor@gmail.com
Mon Nov 9 18:47:00 GMT 2015


On 11/08/2015 12:11 PM, Florian Weimer wrote:
> On 11/06/2015 01:32 PM, David Brown wrote:
>> How about this case:
>>
>> int foo(int x) {
>> 	if (x > 1290) {
>> 		printf("X is wrong here %d, but we don't care\n", x);
>> 	}
>> 	return x*x*x;
>> }
>>
>> The compiler can eliminate the check and the printf.
>
> I don't think the compiler can do that because printf has an externally
> visible effect, which is sequenced before the undefined behavior, so
> this program transformation would not be permitted under the as-if rule.

The standard doesn't prevent such a transformation and compilers,
including GCC, do in some cases, perform it. For example, in the
function below, they eliminate the puts call on the assumption
that x and y cannot alias the same object. When the pointers do
alias, such programs then end up crashing (or obtaining a value
other than 0) in the return statement without printing "undefined
behavior" (but after printing "x[0] = 0").

I agree with the observation that undefined behavior is a property
of the whole program that in general cannot, without sacrifices to
efficiency, be isolated in the control flow of the program to the
point at which the construct that triggers it is reached.

   long foo (long *x, double *y)
   {
     *x = 0;
     *y = 3.14;

     if (*x) puts ("undefined behavior");

     printf ("x[%lu] = %lx\n", *x, x [*x]);

     return x [*x];
   }

   long bar (long a) {
     return foo (&a, &a);
   }

Martin



More information about the Gcc-help mailing list