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.