Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why should the output of this C code be "no"? [duplicate]

I came across this question.

#include <stdio.h>

int main(void) {
    // your code goes here
    unsigned int i = 23;
    signed char c = -23;

    if (i > c)
        printf("yes");
    else
        printf("no");

    return 0;
}

I am unable to understand why the output of this code is no.

Can someone help me in understanding how the comparison operator works when comparison is done between int and char in C ?

like image 601
asad_hussain Avatar asked Jul 17 '16 06:07

asad_hussain


1 Answers

You are comparing an unsigned int to a signed char. The semantics of this kind of comparison are counter-intuitive: most binary operations involving signed and unsigned operands are performed on unsigned operands, after converting the signed value to unsigned (if both operands have the same size after promotion). Here are the steps:

  • The signed char value is promoted to an int with the same value -23.
  • comparison is to be performed on int and unsigned int, the common type is unsigned int as defined in the C Standard.
  • The int is converted to an unsigned int with value UINT_MAX - 23, a very large number.
  • The comparison is performed on the unsigned int values: 23 is the smaller value, the comparison evaluates to false.
  • The else branch is evaluated, no is printed.

To make matters worse, if c had been defined as a long, the result would have depended on whether long and int have the same size or not. On Windows, it would print no, whereas on 64 bit Linux, it would print yes.

Never mix signed and unsigned values in comparisons. Enable compiler warnings to prevent this kind of mistake (-Wall or -Weverything). You might as well make all these warnings fatal with -Werror to avoid this kind of ill-fated code entirely.

For a complete reference, read the following sections of the C Standard (C11) under 6.3 Conversions:

  • integer promotions are explained in 6.3.1.1 Boolean, characters, and integers.
  • operand conversions are detailed in 6.3.1.8 Usual arithmetic conversions.

You can download the latest draft of the C11 Standard from the working group website: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf

like image 85
chqrlie Avatar answered Oct 24 '22 16:10

chqrlie