CSC447

Concepts of Programming Languages

C: Undefined Behavior

Instructor: James Riely

Video

Open on youtube (Lecture Playlist)

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
          

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

Haskell Optimization

Undefined behavior: dangling pointers

See the worksheet for this week.

More examples of undefined behavior

More about undefined behavior

Safe languages

Safe languages do not have undefined behaviors

Lisp is probably the first safe language

Java is the first widely used safe language

assembly
                             z = z + 1;                     z = z + 1;    
                             z = z * z;                     z = z + (z * z);
                             z = z + z;              
assembly