Search code examples
cif-statementbit-manipulationbitwise-operators

How `(1U << 1) | (1U << 5)` is different from `0x22`?


Would someone please explain me how having the same value VAL1 and VAL2 behave differently? For the first if statement VAL1 is equal to zero? Thanks!

#include <stdio.h>

#define VAL1 (1U << 1) | (1U << 5)
#define VAL2 0x22

int main()
{
    printf("VAL1: %d\r\n", VAL1);
    printf("VAL2: %d\r\n", VAL2);

    if (VAL1 == 0)
    {
        printf("TRUE 1\r\n");
    }

    if (VAL2 == 0)
    {
        printf("TRUE 2\r\n");
    }

    if (VAL1 == VAL2)
    {
        printf("TRUE 3\r\n");
    }
}

Output:

VAL1: 34
VAL2: 34
TRUE 1
TRUE 3

Solution

  • In if (VAL1 == 0), macro replacement changes the source code to if ((1U << 1) | (1U << 5) == 0).

    The expression inside the if is evaluated as (1U << 1) | ((1U << 5) == 0), due to a desire to keep C’s operator precedences consistent with those of the earlier language B.

    Thus we have if ((1U << 1) | ((1U << 5) == 0)), in which (1U << 1) evaluates to 2 and ((1U << 5) == 0) evaluates to 0, resulting in if (2 | 0), which becomes if (2), so the statement with the if is executed.

    It is customary to define a macro replacement that is an expression with parentheses to ensure it is grouped as one item:

    #define VAL1 ((1U << 1) | (1U << 5))