Difference between undefined, unspecified, and implementation-defined behavior

Question:

Many times we talk about undefined, unspecified and implementation-defined behavior in c . However, what is the difference between these concepts?

Answer:

Undefined behavior

It appears when the behavior of an algorithm has errors that, although they generate valid code, the final result will depend on factors as strange as the platform on which it is executed or the compiler chosen to generate the program.

char* cadena = "Hola a todos";
cadena[0] = 'h';

The example above causes undefined behavior because the string is likely to be stored in a read-only region. In that case, attempting to modify it will cause a run-time error. On the other hand, if the string is stored in a region of memory that supports writes, the code will work without problems.

Other examples of undefined behavior:

free on unreserved memory

int* ptr;
free(ptr);

call free twice in a row (particularity of the previous case)

int* ptr = (int*)malloc(sizeof(int));
free(ptr);
free(ptr);

Division by 0

int a = 10;
int b = a/0;

Skip return

int func(int a, b)
{
  int c = a + b;
}

In this case, there will be compilers that may show you a warning but it is not advisable to get used to depending on them since it is not something that will be guaranteed (the one that appears).

Unspecified behavior

We find unspecified behavior in those situations in which the standard gives the compiler some freedom when choosing the order in which the instructions are executed.

void func(int a, int b)
{
  printf("%d %d",a,b);
}

int i=0;
func(i++,i++);

The above example can print multiple results:

0 0
0 1
1 0

And it all depends on the order in which the increments are evaluated … which depends on the compiler.

Scroll to Top