I ran into an error recently where a variable was initialized inside a switch statement. I started playing around with this more and realize I don't know the first thing about what GCC is trying to do in some of these optimizations.
int main(int argc, char** argv) { switch (argc) { case 1000: return 42; int y = 24; default: return y; } return argc; } The generated code always returns 42. What is going on? Why does the int y = 24 muck everything up?
$ gcc -Wall -Werror -O2 -c test.c $ objdump -drwCS -Mintel test.o testo.o: file format elf64-x86-64 Disassembly of section .text.startup: 0000000000000000 <main>: 0: b8 2a 00 00 00 mov eax,0x2a 5: c3 ret
ywould be undefined behavior as the initialization of that variable can never be reached, hence the compiler is free to assume that only the1000case can ever happen. (From the compilers point of view, things which would be undefined behavior can never happen and it optimizes accordingly)defaultwith a return in the switch. Since this return is undefined behavior, the wholedefaultcase can never happen, soargcmust be1000. To make this clear, the compiler doesn't just remove undefined paths, it assumes these paths can never happen when you run the program, thats why the compiler assumesargccan never be anything other than1000at runtime.argcis not 1000? You don't know, the compiler doesn't know. The lineint y = 24;never executes, so you're returning a uninitialized value, which the compiler doesn't like at all. Since it's uninitialized anyway, it can just return42as you're not allowed to assume any particular value to be returned. 42 is just as good as 1, 15 or -3546465. Is uninitialized, undefined.