Probelm with bit and byte interpretation

thatoneguy

Joined Feb 19, 2009
6,359
I'm not sure if this is a typo, or what, but your code has some issues.

unsigned short bytr is in function, but never used, then you are using the byte keyword in the bit shifting.

If using byte, it will be signed. You should declare the universal u_int8 for an unsigned 8 bit number (or char in old school keywords).

Since you didn't post the updated code of what you changed to make it work, it's a bit hard to explain why it works now.
 

WBahn

Joined Mar 31, 2012
30,061
It should just invert the bits, but the behavior of the bitwise operators is only specified for unsigned integer types. So try making your variable an unsigned short.
 

takao21203

Joined Apr 28, 2012
3,702
byte is a bad variable name. Don't use it as variable name.

If you use any such words which could resemble a type or structure name, use them that way: byte_0, byte_1, etc.
 

thatoneguy

Joined Feb 19, 2009
6,359
It should just invert the bits, but the behavior of the bitwise operators is only specified for unsigned integer types. So try making your variable an unsigned short.
With GNU C, it allows bitwise negation as well as shifting of signed numbers, but the results are unpredictable.

From: This Link with visual explanations


This link also explains how AVR promotes char to uint in some operations which would also explain the change in your code comparisons if the byte was promoted to a 16 bit integer.

I usually define (rather than typedef) uint8 to: u_int8, and, uchar. having the u_ vs uint8 makes the unsigned stand out a bit more, and it helps work with code others have written.

Rich (BB code):
Noncompliant Code Example (Left Shift, Unsigned Type)

The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. According to the C standard, if E1 has an unsigned type, the value of the result is E1 * 2E2, reduced modulo one more than the maximum value representable in the result type.
This  noncompliant code example can result in undefined behavior because  there is no check to ensure that the right operand is less than or equal  to the width of the promoted left operand.
 unsigned int ui1;
unsigned int ui2;
unsigned int uresult;
 
/* Initialize ui1 and ui2 */
 
uresult = ui1 << ui2;



 

Compliant Solution (Left Shift, Unsigned Type)

This  compliant solution eliminates the possibility of undefined behavior  resulting from a left-shift operation on unsigned integers.
 unsigned int ui1;
unsigned int ui2;
unsigned int uresult;
 
/* Initialize ui1 and ui2 */
 
if (ui2 >= sizeof(unsigned int)*CHAR_BIT) {
  /* handle error condition */
} else {
  uresult = ui1 << ui2;
}
 

WBahn

Joined Mar 31, 2012
30,061
Agreed, it should generate a compiler warning, similar to using the assignment = in a location where == is typically used.
Ideally it should, but I don't think there is any requirement to do so. For the = vs ==, some compilers produce a warning but this definitely is not required behavior since both operations are not only valid syntactically, but both are clearly defined. Many people use the assignment in a conditional expression deliberately and do not want to see bogus (from their perspective) warnings that might obscure other, valid warnings.
 
Top