Hi, Take as reference the code below (compiled using gcc-4.4.1 on linux. command line: g++ main.cpp): int main() { bool value = true; if (value) printf("true\n"); if (!value) printf("false\n"); return 0; } The first 'if' generates the following block: cmpb $0, 31(%esp) je .L2 movl $.LC0, (%esp) call puts While the second 'if' generates the following: .L2: movzbl 31(%esp), %eax xorl $1, %eax testb %al, %al je .L3 movl $.LC1, (%esp) call puts I think this: movzbl 31(%esp), %eax xorl $1, %eax testb %al, %al je .L3 Could be replaced by this: cmpb $0, 31(%esp) jne .L3 Is there a reason to be like this? Am I missing something? This change will remove two instructions per comparison and also solve a strange behavior, which was the original reason for me to investigate it; Take as an example a non-initialized bool variable, containing the value 0x8 (trash memory). The two lines below will be printed: if (value) printf("true"); if (!value) printf("also true"); since the second 'if' will compute (0x1 xor 0x8) resulting in 0x9 (also true). Maybe the spec doesn't care about this, but I think this is a strange behavior even for non-initialized variables. Br, Adriano
> Am I missing something? -O1 / -O2 / -O3 / -Os option. > but I think this is a strange behavior > even for non-initialized variables. http://en.wikipedia.org/wiki/Undefined_behavior
>> Am I missing something? > -O1 / -O2 / -O3 / -Os option. I know about these optimization flags :). My suggestion is directed specifically to -O0. I would not rest knowing that it generates 4 instructions per comparison, while it could use 2 instructions, reducing my code size and my compilation time while using -O0, which is the default one. >> but I think this is a strange behavior >> even for non-initialized variables. > http://en.wikipedia.org/wiki/Undefined_behavior I also know about UB. The strange behavior I'm referring to regards the compiler implementation rather than the language specification. I just looked for this, because I expected a consistent behavior in gcc for non-initialized bool values in that matter. For example, for char types it wouldn't make sense a == !a, for whatever value randomly placed in those 8 bits. For the 'if' statements, I expected a mutual exclusive operation, like [if(a) - cmpb/je] and [if(!a) - cmpb/jne], and that wasn't happening for bool comparisons. Well, I'm not an asm programmer nor a gcc contributor, so I may be wrong. But unless those 4 instructions make some sense, there is no purpose in keeping them.
(In reply to comment #2) > My suggestion is directed specifically to -O0. If you want optimised code then use optimisation. > I also know about UB. The strange behavior I'm referring to regards the > compiler implementation rather than the language specification. I just looked > for this, because I expected a consistent behavior in gcc for non-initialized > bool values in that matter. No. You cannot expect undefined behaviour to be consistent.
(In reply to comment #2) > >> Am I missing something? > > > -O1 / -O2 / -O3 / -Os option. > > I know about these optimization flags :). > My suggestion is directed specifically to -O0. > > I would not rest knowing that it generates 4 instructions per comparison, while > it could use 2 instructions, reducing my code size and my compilation time > while using -O0, which is the default one. GCC is known to generate very bad code at -O0, but this is expected. The reason is that GCC makes sure !value is computed into a register (for the sake of debugging), thus does temp = !value; if (temp) ...
> GCC is known to generate very bad code at -O0, but this is expected. > > The reason is that GCC makes sure !value is computed into a register > (for the sake of debugging), thus does > > temp = !value; > if (temp) > ... Thanks for the explanation, it makes sense now :)
Please do not reopen bugs closed as invalid.