Q:

Difference between ! and ~

I was implementing a simple state machine as follows:
typedef void V_V_StateFunc(void);
static V_V_StateFunc *const fpCurrentStateFunc[STATE_ELEM_SIZE]={

    &fn1,/*0*/

};

void Execute_StateMachine(const U8 bCurrent_StateIndex)
{
    if(bStateIndex == (~bInvert_StateIndex))
    {
        if(bCurrent_StateIndex <= STATE_ELEM_SIZE)
        {
            fpCurrentStateFunc[bCurrent_StateIndex]();
        }
        else
        {
            /*this should never enter*/
        }   
    }
    else
    {
            /*this should never enter*/
    }
}

void Update_State(U8 bNewIndex)
{
    bStateIndex=bNewIndex; //bStateIndex & bInvert_StateIndex are globals
    bInvert_StateIndex=(~bNewIndex);
}

In the function Execute_StateMachine(), if I check bStateIndex == (~bInvert_StateIndex), the value is always 0 and nevers enter the if statement, though bStateIndex=0 and ~bInvert_StateIndex=0 (i.e 0 == 0, which is true). 
Why is this happening?
If I change bStateIndex == (!bInvert_StateIndex),it enters the if statement.
What is the difference between ~ and ! here?

A:

the ! operator is the logical not operator; for example the expression
if (!variable)

is equal to:
if (variable == 0)

The ~ operator is the bitwise NOT operator; thus changing the value of each bit.
 char variable = 1;           // value: 00000001
 char variable2 = ~variable;  // value: 11111110 = 254  (as noted by @Lundin; value = 11111111 11111111 11111111 11111110 and then truncated to 11111110 upon assignment to char)

A:

I would guess it happens because of integer promotion. The ~ operator is a dangerous one to use, since its operand is integer promoted. So the promoted operand is of type int here and not U8 as you might think. 
Meaning that if you pass the value 0xFF to ~, the result will be not be 0x00 as you might expect, but 0xFFFFFF00. Temporarily stored in a signed int.
Avoid this by always casting the result of the ~ operator to the intended type:
bStateIndex == (U8)(~bInvert_StateIndex)

