5 ms·
You can fulfill (1) not too hard. First, the compiler is allowed to compile your program as-if all values of all variables are such that undefined behaviour do
by Asooka 8y ago
You can fulfill (1) not too hard.
First, the compiler is allowed to compile your program as-if all values of all variables are such that undefined behaviour doesn't happen, but isn't allowed to extract value bounds based on that for the purposes of optimising across more than one expression. So the compiler is allowed to assume pointers aren't NULL where they are dereferenced, because that is undefined behaviour and the compiler either has to assume the pointer isn't NULL, or require proof from the programmer, or refuse to compile any C program with pointer dereferencing because it is potentially invalid C. However, it is not allowed to assume that because a pointer was dereferenced, that it is not NULL. This restriction should be tight enough that
int a, b;
... set a and b ...
if (a > 0 && b > 0 && (a+b)&(int)(-1) > a) {
...
} else {
...
}
is compiled to something like
mov eax a
add eax b
cmp eax a
jle .else
Second, you can define "trivially compiled C" for every platform as a set of substitution rules that transform every C operation into machine instructions without any optimization. Such a trivial compilation would have every variable write correspond to a memory write, keep no variables in registers, always compile the same expression to the exact same machine code (except for memory addresses of variables involved), never inline functions etc. But it would still be allowed to e.g. put 32-bit integers in 64-bit registers on the basis that int operations are assumed not to overflow. The committee should define that for every supported platform as a reference C compiler, then require that C compilation produce machine code with observable side-effects for single-threaded execution equivalent to the reference trivially compiled C.
- palotasb 8y agoIsn't the reference compiler with trivial compilation equivalent to trying to make all UB implementation-defined where the implementation is the "trivial compilation"? For example this would preclude optimization based on aliasing rules which a lot of tight loops rely on. float max (float f[], int length, int* max_index) { float max_value = -FLT_MAX; *max_index = -1; for (int i = 0; i < length; i++) { if (max_value < f[i]) { *max_index= i; max_value = f[i]; } } return max_value; } Take the code above. It obviously has a well-defined trivial compilation implementation even for cases where max_index aliases an element of the f[] array. There is a good reason that implementations are allowed to assume that doesn't happen: it produces better code in the case where the program has no bugs. Otherwise even at -O3, the implementation would have to read f[i] twice from memory as the value might have changed when *max_index was written if it wants the same behavior as the "trivial compilation" implementation.
- obl 8y ago> Second, you can define "trivially compiled C" for every platform as a set of substitution rules that transform every C operation into machine instructions without any optimization. Such a trivial compilation would have every variable write correspond to a memory write, keep no variables in registers, always compile the same expression to the exact same machine code (except for memory addresses of variables involved), never inline functions etc. But it would still be allowed to e.g. put 32-bit integers in 64-bit registers on the basis that int operations are assumed not to overflow. The committee should define that for every supported platform as a reference C compiler, then require that C compilation produce machine code with observable side-effects for single-threaded execution equivalent to the reference trivially compiled C. Such an approach would preclude putting any variable in a register if there is any not-provably-valid pointer store anywhere in the program. Feel free to try, but I guarantee you that for most non trivial optimization it's going to be easy to find a piece of code that is UB today and where the optimization is observably different from the reference compilation.