[solved] Left shift behaviour

The other day I was tinkering with an SPI device and noticed that the left shift operator (<<) was not working as expected. My idea was to use the operator to access an individual bit from a byte, such as this:

uint8_t mybyte = B10000000;
if ((mybyte << 1) >> 7)
{
   //do stuff;
}

In this case I would be executing my code if the 2nd bit of mybyte were 1. However, the operator seems to not work as I would expect (from what I know and what is in the refference page, it should just delete the leftmost bit), but instead seems to cast or use mybyte as a 16 bit int, and therefore the previous expression evaluates to true.

The only solution that I could come up with was to cast the result into a byte again, like so:

uint8_t mybyte = B10000000;
if (uint8_t(mybyte << 1) >> 7)
{
   //do stuff;
}

This works just fine, but now my code is an absolute mess. Is this the expected behaviour from the << operand? If yes, are there cleaner ways to achieve what I am after?

since the bit you appear to be interested is the most significant bit and the value is stored in a 8-bit byte, the first shift to the left pushed the bit out of the memory location.

why not

uint8_t mybyte = B10000000;
if ((mybyte >> 7) & 1)
{
   //do stuff;
}

Use a bit-wise 'and' operation to mask the unwanted bit(s): Bitwise Operators in C/C++ - GeeksforGeeks

alpemwarrior:
The only solution that I could come up with was to cast the result into a byte again, like so:

uint8_t mybyte = B10000000;

if (uint8_t(mybyte << 1) >> 7)
{
  //do stuff;
}

You seem to be under the impression that a conditional test only tests the lowest bit. That is not the case, any non-zero value evaluates to 'true'. Thus you can shift a 1 to to desired position instead using compiler arithmetic, and use it as a bit mask. This requires no run time shifting, since the compiler can pre-compute the mask because it's a constant.

uint8_t mybyte = B10000000;
if (mybyte  & (1 << 7))
{
   //do stuff;
}

It should be academic, since you should be naming bits, like:

const uint8_t UART_REGS_DTR = 0x80;
...
uint8_t mybyte = B10000000;
if (mybyte  & UART_REGS_DTR)
{
   //do stuff;
}

because undocumented bit shifts are basically anonymous values.

That makes sense. Thanks!