So it all started here: An unsigned integer and an unsigned char with the same value, but in a different way, why?
I wrote the following application to understand what is going on behind the scenes (for example, how the compiler deals with this problem).
#include <stdio.h> int main() { { unsigned char k=-1; if(k==-1) { puts("uc ok\n"); } } { unsigned int k=-1; if(k==-1) { puts("ui ok"); } } }
And when compiling with GCC:
gcc -O0 -S -masm=intel hc
I get the following build file:
.file "hc" .intel_syntax noprefix .section .rodata .LC0: .string "ui ok" .text .globl main .type main, @function main: .LFB0: .cfi_startproc push rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 mov rbp, rsp .cfi_def_cfa_register 6 sub rsp, 16 mov BYTE PTR [rbp-1], -1 mov DWORD PTR [rbp-8], -1 cmp DWORD PTR [rbp-8], -1 jne .L3 mov edi, OFFSET FLAT:.LC0 call puts .L3: leave .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE0: .size main, .-main .ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3" .section .note.GNU-stack,"",@progbits
And to my great surprise, the first check EVEN.
But, if I compile the same with Microsoft Visual C ++ (2010), I get (I cut a lot of garbage from this listing, why is it not so reliable):
00B81780 push ebp 00B81781 mov ebp,esp 00B81783 sub esp,0D8h 00B81789 push ebx 00B8178A push esi 00B8178B push edi 00B8178C lea edi,[ebp-0D8h] 00B81792 mov ecx,36h 00B81797 mov eax,0CCCCCCCCh 00B8179C rep stos dword ptr es:[edi] 00B8179E mov byte ptr [k],0FFh 00B817A2 movzx eax,byte ptr [k] 00B817A6 cmp eax,0FFFFFFFFh 00B817A9 jne wmain+42h (0B817C2h) 00B817AB mov esi,esp 00B817AD push offset string "uc ok\n" (0B857A8h) 00B817B2 call dword ptr [__imp__puts (0B882ACh)] 00B817B8 add esp,4 00B817BB cmp esi,esp 00B817BD call @ILT+435(__RTC_CheckEsp) (0B811B8h) 00B817C2 mov dword ptr [k],0FFFFFFFFh 00B817C9 cmp dword ptr [k],0FFFFFFFFh 00B817CD jne wmain+66h (0B817E6h) 00B817CF mov esi,esp 00B817D1 push offset string "ui ok" (0B857A0h) 00B817D6 call dword ptr [__imp__puts (0B882ACh)] 00B817DC add esp,4 00B817DF cmp esi,esp 00B817E1 call @ILT+435(__RTC_CheckEsp) (0B811B8h)
Question: Why is this happening? Why does GCC skip the first IF, and how can I get GCC not to skip it? Optimizations are disabled, but it looks like it is still optimizing something ...