CSC447

Concepts of Programming Languages

C: Undefined Behavior

Instructor: James Riely

Undefined behavior: under/overflow


#include <stdio.h>

int isMinValue (int x) {
  return (x-1) > x;
}
int main () {
  int i = -2000000000;  
  while (!isMinValue(i))
    i--;
  printf ("Min value is %d\n", i);
}
          

$ gcc -O1 undefined.c && ./a.out 
Min value is -2147483648
          

$ gcc -O2 undefined.c && ./a.out 
^C #infinite loop
          

Why?

Undefined Behavior: Order of operations


#include <stdio.h>
int count = 0;
int f () {
  count += 1;
  return count;
}
int main () {
  int z = f() + f();
  printf ("%d\n", z);
  z = (z += 1) + (z = z*z);
  printf ("%d\n", z);
}
          

$ clang -Wall undefined3.c 
undefined3.c:11:21: warning: unsequenced modification and access to 'z'
  z = (z += 1) + (z = z*z);
         ~~         ^
1 warning generated.
$ ./a.out 
3
20
            

Undefined Behavior: Order of operations


#include <stdio.h>
int count = 0;
int f () {
  count += 1;
  return count;
}
int main () {
  int z = f() + f();
  printf ("%d\n", z);
  z = (z += 1) + (z = z*z);
  printf ("%d\n", z);
}
          

$ gcc -Wall -O3 undefined3.c 
undefined3.c: In function ‘main’:
undefined3.c:11:5: warning: operation on ‘z’ may be undefined
   z = (z += 1) + (z = z*z);
     ^
$ ./a.out 
3
32
          
assembly
                             3 32                           3 20
                             z = z + 1;                     z = z + 1;    
                             z = z * z;                     z = z + (z * z);
                             z = z + z;              

Undefined behavior and compiler optimizations

For undefined executions, the compiler can do what it likes.

This can lead to some surprising compiler optimizations.

C null pointer optimization 1 (Discussion) (Discussion)

C null pointer optimization 2

Undefined behavior: dangling pointers

See the optional exercises on the worksheet from week 1.

More examples of undefined behavior

More about undefined behavior

assembly

Safe languages

Safe languages do not have undefined behaviors

Lisp is probably the first safe language

Java is the first widely used safe language