Understanding "Bitwise-And (&)" and "Unary complement(~)" in c++
Question: I have some trouble understanding `Bitwise-And` and `Unary Complement` when
both are used in this code snippet

    
    
    if((oldByte==m_DLE) & (newByte==m_STX)) {
        int data_index=0;
    
       //This below line --- does it returns true if both the oldByte and newByte are not true 
       //and within timeout 
    while((timeout.read_s()<m_timeout) & ~((oldByte==m_DLE) & (newByte==m_ETX))) { 
    
                            if(Serial.available()>0) {
                                oldByte=newByte;
                                newByte=Serial.read();
    
                                if(newByte==m_DLE) {
                                .
                                .
                                .
    

are the both operators `& ~`are performing a logical not operation like
checking until if both `oldByte` and `newByte` are false

The above code is from the [link](https://github.com/GraemeWilson/Arduino-
Python-Framing-
CRC16/blob/af28e4c5106505c7d1227bf840fef55db0f679af/Arduino/Framing.cpp) \-->
line 227 of the code

I am trying to use the implement the code for my application in C but without
the timing functions

    
    
     if((oldByte==DLE) && (newByte== STX)) {
        data_index = 0;
         // is this the correct implematation for above C++ code to C  
        while(! ((oldByte== DLE) && (newByte== ETX))){
              oldByte = newByte;
    

Is this method correct for implementing in C


Answer: 
    (timeout.read_s()<m_timeout) & ~((oldByte==m_DLE) & (newByte==m_ETX))
    

is equivalent to (but probably less readable than)

    
    
    (timeout.read_s()<m_timeout) && !(oldByte==m_DLE && newByte==m_ETX)
    

which is equivalent to (and IMO less readable than)

    
    
    (timeout.read_s()<m_timeout) && (oldByte!=m_DLE || newByte!=m_ETX)
    

Edit: should add a caveat about short-circuiting. Although the particular
example statements will all return the same value, using && or || will skip
evaluating pieces that can't impact the result. This isn't important in your
specific example, but could be very important in an example like this:

    
    
    (oldByte!=nullptr & *oldByte == m_ETX) // will crash when oldByte=nullptr.
    
    (oldByte!=nullptr && *oldByte == m_ETX) // will evaluate to false when oldByte=nullptr.
    

