'Why does gcc optimize out this comparison and how can I get it to get compiled in?

unsigned char c;
int n;

int main(){ 
 if ((c && 0xc0) == 0xc0 )  { 
        n=0; 
      }
}

When testing on godbolt, only gcc does this.



Solution 1:[1]

It's actually very simple. Since you use && as an operator, gcc can deduce that the condition always yields false.

If you use the bitwise and operator (&), gcc adds code for the if:

#include <stdio.h>
unsigned char c = 0xff;
int n = 1;

int main(){ 
 if ((c & 0xc0) == 0xc0 )  { 
        n=0; 
      }
  printf("%d\n", n);
}

yields:

ronald@oncilla:~/tmp$ cc -S x.c && cat x.s
    .file   "x.c"
    .text
    .globl  c
    .data
    .type   c, @object
    .size   c, 1
c:
    .byte   -1
    .globl  n
    .align 4
    .type   n, @object
    .size   n, 4
n:
    .long   1
    .section    .rodata
.LC0:
    .string "%d\n"
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    endbr64
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movzbl  c(%rip), %eax
    movzbl  %al, %eax
    andl    $192, %eax
    cmpl    $192, %eax
    jne .L2
    movl    $0, n(%rip)
.L2:
    movl    n(%rip), %eax
    movl    %eax, %esi
    leaq    .LC0(%rip), %rdi
    movl    $0, %eax
    call    printf@PLT
    movl    $0, %eax
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .ident  "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04) 9.4.0"
    .section    .note.GNU-stack,"",@progbits
    .section    .note.gnu.property,"a"
    .align 8
    .long    1f - 0f
    .long    4f - 1f
    .long    5
0:
    .string  "GNU"
1:
    .align 8
    .long    0xc0000002
    .long    3f - 2f
2:
    .long    0x3
3:
    .align 8
4:

Solution 2:[2]

In C && casts operands to bool which even though its an int, it is changed to 1 meaning true, if nonzero.

& is a bitwise and, which returns the bits that are the same. If you combine this with && it returns true if there are any bits left.

If you compile with -Wall you will get a warning when something gets optimized out at compile time.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ronald
Solution 2