3 ms·
C: #include <stdio.h> #include <stdbool.h> #include <stdlib.h> int nums[5] = {1, 0, 1, 0, 1}; static int cur; int main(int argc, char
by comex 12y ago
C:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
int nums[5] = {1, 0, 1, 0, 1};
static int cur;
int main(int argc, char **argv) {
for(int i = 1; nums[i] != 5 && i < 10; i++) {
cur = i;
if(i/4 == 1) {
printf("2 + 2 <= %d = %s\n", cur, 2 + 2 <= i ? "true" : "false");
printf("2 + 2 == %d = %s\n", cur, 2 + 2 == i ? "true" : "false");
printf("\n");
}
}
}
No strange array writes! No indirect writes at all!
It's finicky and I believe depends on register allocation, but when I compile it using whatever version of gcc-mp-4.9 I have installed from MacPorts at -O3, it outputs, among other things:
2 + 2 == 5 = true
(For all they say about evil optimizing compilers, it was really hard to make this work.)
- tgb 12y agoCan anyone explain? It didn't work for me but still gives odd results depending on optimization level that I don't understand.
- comex 12y agoBecause nums is a length 5 array, and the loop condition checks nums[i], GCC assumes going into the loop that i is a valid index, i.e. i <= 4. The division then rules out the possibility that i < 4, so for the purposes of optimization, my version of GCC thinks that i always equals 4 at the printfs, even if it's actually higher. It's based on an old Linux bug... I should learn more about GCC internals in order to tell tell why I couldn't get it to work without a loop. In general, any sequence where some property not holding would cause undefined behavior to occur allows a conforming compiler to assume it does hold, but for most basic examples neither GCC nor Clang does anything special.
- tgb 12y agoGreat explanation and fun exploit, thanks!