#include
#include
int shift(int x, int n) { return x << n; }
int main(int argc, char **argv) {
printf("%d\n", shift(1, 32)); /* n == width: UB */
return 0;
}
This program exhibits UB in Fil-C, and you can see that the optimizer does different things at -O0 (outputs 1) and -O1/-O2/-O3 (outputs 0). Since this creates poison, which Fil-C doesn't remove, you can use it to construct all kinds of weird things.
static void loop(void) {
int s = shift(1, 32);
int n = 0;
for (int i = 0; i < s + 3; i++)
n++;
printf("[loop] iterations=%d (s+3=%d)\n", n, s + 3);
}
static void sw(void) {
switch (shift(1, 32)) {
case 0: puts("[switch] case 0"); break;
case 1: puts("[switch] case 1"); break;
default: puts("[switch] default"); break;
}
}
int main(int argc, char **argv) {
loop();
sw();
return 0;
}
In Fil-C -O0, this gives 4 iterations of the loop and executes sw(). At any higher optimization level, it turns loop() into an infinite loop and drops sw() from the binary entirely.
Neither of those sound like Undefined Behaviour to me, they're maybe unspecified but they don't sound undefined at all - are you confusing Undefined Behaviour with "I wanted it to do something else" ?
You said "explode" earlier and so I was expecting something a bit more dramatic than "Unsurprisingly Fil-C has unspecified results for some expressions".