what will be the value of ~(true) in environment? and need answer justification

48 views Asked by At

I came across a weird observation recently when I came across below piece of program.

// Write C code here

bool abc = true;
bool cba = true;
bool bac = ~abc;

if(cba && bac)
{
    printf("\nYES! %d", bac);
}
else
{
    printf("\nNO! %d", bac);
}
return 0;

In the above program, I have observed that even though abc is true, if statement is getting executed and not else. Any explanation would be appreciated.

Note: But the same with " bool bac = !abc;", working as expected.

2

There are 2 answers

0
0___________ On
  1. The difference between ! and ~.
  • ! logical not. Any non-zero value becomes zero and zero becomes 1
  • ~ bitwise not - negates all bits in the bitwise representation of the value. It can be applied to integer values only. ~1 becomes -2 in two complement integers

C standard 7.16.3:

The remaining three macros are suitable for use in #if preprocessing directives. They are true which expands to the integer constant 1, false which expands to the integer constant 0

6.2.5.2

An object declared as type _Bool is large enough to store the values 0 and 1.

The smallest type is char and it has size (in bits) of CHAR_BIT (minimum 8)

Implicit conversions apply:

bool abc = true;
bool bac = ~abc;
  1. abc is converted to int and has the value 1
  2. ~ operation is applied to the int value 1
  3. The result - which is not zero is converted back to bool - and it has value true as in C language any non-zero value is considered true.
  4. bac has value true

what will be the value of ~(true)

It will be an integer and it will have the value of ~1

The only way to ~ to reverse logical value is to use integer bitfield of size 1

typedef struct
{
    unsigned val:1;
}mybool;

int main(void)
{
    mybool abc = {true};
    mybool cba = {true};
    mybool bac = {~abc.val};

    if(cba.val && bac.val)
    {
        printf("\nYES! %u", bac.val);
    }
    else
    {
        printf("\nNO! %u", bac.val);
    }
}

https://godbolt.org/z/bjz6T4vTK

0
Vlad from Moscow On

The unary operators ! and ~ have different effects. From the C Standard (6.5.3.3 Unary arithmetic operators)

5 The result of the logical negation operator ! is 0 if the value of its operand compares unequal to 0, 1 if the value of its operand compares equal to 0. The result has type int. The expression !E is equivalent to (0==E).

So in this line

bool bac = !abc;

the result of the expression !abc is 0. And this value is assigned to the variable bac.

As a result the condition with the logical AND operator in the if statement

cba && bac

evaluates also to 0.

4 The result of the ~ operator is the bitwise complement of its (promoted) operand (that is, each bit in the result is set if and only if the corresponding bit in the converted operand is not set). The integer promotions are performed on the operand, and the result has the promoted type. If the promoted type is an unsigned type, the expression ~E is equivalent to the maximum value representable in that type minus E.

So in this line

bool bac = ~abc;

the operand abc of the operator ~ is promoted to the type int and if sizeof( int ) is equal to 4 then the result will be FFFFFFFE that is not equal to 0. Assigning this non-zero expression to the variable bacmakes the variable equal to 1.

As a result the condition with the logical AND operator

cba && bac

also will be equal to 1.