The C language standard precisely specifies the observable behavior of C language programs, except for the ones in the following categories:
islower returns true for any character other than the 26 lowercase Latin letters. (Note: Strictly conforming programs do not depend on any unspecified, undefined, or implementation-defined behavior).
The compilers are required to issue diagnostic messages (either errors or warnings) for any programs that violates any C syntax rule or semantic constraint, even if its behavior is specified as undefined or implementation-defined or if the compiler provides a language extension that allows it to accept such program. Diagnostics for undefined behavior are not otherwise required.
Because correct C programs are free of undefined behavior, compilers may produce unexpected results when a program that actually has UB is compiled with optimization enabled:
For example,
int foo(int x) {
return x+1 > x; // either true or UB due to signed overflow
}may be compiled as (demo).
foo(int):
movl $1, %eax
retint table[4] = {};
int exists_in_table(int v)
{
// return true in one of the first 4 iterations or UB due to out-of-bounds access
for (int i = 0; i <= 4; i++) {
if (table[i] == v) return 1;
}
return 0;
}May be compiled as (demo).
exists_in_table(int):
movl $1, %eax
retbool p; // uninitialized local variable
if(p) // UB access to uninitialized scalar
puts("p is true");
if(!p) // UB access to uninitialized scalar
puts("p is false");May produce the following output (observed with an older version of gcc):
p is true p is false
size_t f(int x)
{
size_t a;
if(x) // either x nonzero or UB
a = 42;
return a;
}May be compiled as (demo).
f(int):
mov eax, 42
retChoose clang to observe the output shown.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *p = (int*)malloc(sizeof(int));
int *q = (int*)realloc(p, sizeof(int));
*p = 1; // UB access to a pointer that was passed to realloc
*q = 2;
if (p == q) // UB access to a pointer that was passed to realloc
printf("%d%d\n", *p, *q);
}Possible output:
12
Choose clang to observe the output shown.
#include <stdio.h>
int fermat() {
const int MAX = 1000;
int a=1,b=1,c=1;
// Endless loop with no side effects is UB
while (1) {
if (((a*a*a) == ((b*b*b)+(c*c*c)))) return 1;
a++;
if (a>MAX) { a=1; b++; }
if (b>MAX) { b=1; c++; }
if (c>MAX) { c=1;}
}
return 0;
}
int main(void) {
if (fermat())
puts("Fermat's Last Theorem has been disproved.");
else
puts("Fermat's Last Theorem has not been disproved.");
}Possible output:
Fermat's Last Theorem has been disproved.
C++ documentation for undefined behavior |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
http://en.cppreference.com/w/c/language/behavior