Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing uint8_t with a number

Tags:

c++

c

keil

Maybe I do not understand C++ properly or is it a compiler's bug?

uint8_t a = 0x00;
uint8_t b = 0xFF;

if( a - b == 1 )
{
    doNothing();
}

doNothing is not called (as expected), because result of (a-b) was implicitly casted to the type of second operand in compare operation. And for numbers it's signed int. Okay.

if( a - b == (uint8_t)1 )
{
    doNothing();
}

doNothing STILL isn't called, but now I do not understand the reason for it! I have explicitly casted the number to uint8!

if( (uint8_t)(a - b) == 1 )
{
    doNothing();
}

Now doNothing is finally called, but again why? How can subtraction of two uint8 return an int?

Compiler is uVision ARMCC for ARM Cortex M3.

like image 653
Amomum Avatar asked Sep 26 '13 17:09

Amomum


People also ask

What does uint8_t mean?

uint8_t means it's an 8-bit unsigned type. uint_fast8_t means it's the fastest unsigned int with at least 8 bits. uint_least8_t means it's an unsigned int with at least 8 bits.

Can we compare int8_t and uint8_t?

An integral promotion for uint8_t and int8_t is possible to int , so it is obligatorily applied. Therefore the comparison between a uint8_t and int8_t is transformed by the compiler into a comparison between 2 int . There is no undeterministic behaviour.

What is the difference between uint8_t and int?

In simple terms, UINT8_T is defined for simplicity.. It just means Unsigned 8 bit integer. "int" is very abstract nowadays... Some compilers default to unsigned 8 bit integer and others to signed 8 bit integer.

What is uint16_t in C?

uint16_t is unsigned 16-bit integer. unsigned short int is unsigned short integer, but the size is implementation dependent. The standard only says it's at least 16-bit (i.e, minimum value of UINT_MAX is 65535 ).


2 Answers

ARM Cortex M3 is a 32 bit processor. So result of a - b is 0xFFFFFF01 which is not equal to 1 (1 ==> 0x00000001 in 32 bit representation) so doNothing() function is not called!

In case 2, if you typecast 1 to uint8_t, which is 0xFFFFFF01 is not equal to 0x01 so doNothing() function not called again!

In case 3, when you typecast a - b output to uint8_t then a - b result is 0x01 which is equal to 1, hence doNothing is called.

like image 128
Basavaraju B V Avatar answered Sep 29 '22 12:09

Basavaraju B V


In a - b, the operands are promoted to int before the subtraction, so the result is -255, not 1.

That's why both the first and second examples fail; it's nothing to do with the other operand of ==. The third converts -255 back to uint8_t, reducing it modulo 256, so the result is 1 as expected.

like image 34
Mike Seymour Avatar answered Sep 29 '22 13:09

Mike Seymour