Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrong result with bitwise inclusive OR

I can't figure out why does inclusive OR return wrong result.

char arr[] = { 0x0a, 0xc0 };
uint16_t n{};

n = arr[0]; // I get 0x000a here.
n = n << 8; // Shift to the left and get 0x0a00 here.
n = n | arr[1]; // But now the n value is 0xffc0 instead of 0x0ac0.

What is the mistake in this example? Console app, MVS Community 2017.

like image 871
Konstantin Avatar asked Oct 27 '25 03:10

Konstantin


1 Answers

The unintended 0xff is caused by sign bit extension of 0xc0.

0xc0 = 0b11000000

Hence, the uppermost bit is set which means sign for char (as signed char).

Please, note that all arithmetic and bitwise operations in C++ work with at least int (or unsigned int). Smaller types are promoted before and clipped afterwards.

Please, note also that char may be signed or unsigned. That's compiler implementation dependent. Obviously, it's signed in the case of OP. To prevent the unintended sign extension, the argument has to become unsigned (early enough).

Demonstration:

#include <iostream>

int main()
{
  char arr[] = { '\x0a', '\xc0' };
  uint16_t n{};

  n = arr[0]; // I get 0x000a here.
  n = n << 8; // Shift to the left and get 0x0a00 here.
  n = n | arr[1]; // But now the n value is 0xffc0 instead of 0x0ac0.
  std::cout << std::hex << "n (wrong): " << n << std::endl;
  n = arr[0]; // I get 0x000a here.
  n = n << 8; // Shift to the left and get 0x0a00 here.
  n = n | (unsigned char)arr[1]; // (unsigned char) prevents sign extension
  std::cout << std::hex << "n (right): " << n << std::endl;
  return 0;

}

Session:

g++ -std=c++11 -O2 -Wall -pthread main.cpp && ./a.out
n (wrong): ffc0
n (right): ac0

Life demo on coliru

Note:

I had to change
char arr[] = { 0x0a, 0xc0 };
to
char arr[] = { '\x0a', '\xc0' };
to come around serious compiler complaints. I guess, these complaints where strongly related to this issue.

like image 64
Scheff's Cat Avatar answered Oct 28 '25 17:10

Scheff's Cat



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!