Note:
If I understand the following code right, it will skip the whole loop, because when compare unsigned
(j) and signed
(-1), it seems that the -1 will be convert to UINT_MAX
. (like this question explained)
The first loop:
unsigned int j = 10;
for (; j > -1; --j) { ---> `>`
printf("%u", j);
}
Part of assembly code of first loop:
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl %edi, -20(%rbp)
movq %rsi, -32(%rbp)
movl $10, -4(%rbp)
nop --->**elision**
popq %rbp
.cfi_def_cfa 7, 8
ret
The second loop of second loop:
unsigned int j = 10;
for (; j >= -1; --j) { ---> `>=`
printf("%u", j);
}
Part of assembly code:
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $32, %rsp
movl %edi, -20(%rbp)
movq %rsi, -32(%rbp)
movl $10, -4(%rbp)
jmp .L2 --->** still a loop here **
.L3:
movl -4(%rbp), %eax
movl %eax, %esi
movl $.LC0, %edi
movl $0, %eax
call printf
subl $1, -4(%rbp)
.L2:
cmpl $-1, -4(%rbp)
je .L3
leave
.cfi_def_cfa 7, 8
ret
So my question is
- Why the gcc (I use GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2) treat a similar situation, it optimize the first one but didn't the second? (* Or my understand of the code is wrong?) (it has something to do with the assembly?)
Edit: You can go to this site to check. If you just use -S
compiler option(or no compiler option) you will get the same result as I do. (Thanks @Raymond Chen for reminder)
step 1:
Open above site and copy the following code to Code Eidtor.
#include <stdio.h>
int main (int argc, char *argv[]) {
unsigned int j = 10;
for (; j > -1; --j) {
printf("%u", j);
}
}
step 2:
Choose g++ 4.8
as compiler. Compiler option is empty.(or -S)
step 3:
You get the first situation. Now, change the j > -1
to j >= -1
and you can see the second.