Go Down

Topic: Use of uint8_t, uint16_t etc (Read 620 times) previous topic - next topic

rbright

I've always wondered what this infuriating code like below is for......
uint8_t minutes = 59;
uint8_t seconds = 59;

instead of say using
int minutes = 59;
int seconds = 59;

For the enlightenment of all readers you may want to visit this link:
https://www.badprog.com/c-type-what-are-uint8-t-uint16-t-uint32-t-and-uint64-t

It seems for example that uint8_t is the same as a 8 bit byte.
And is shorthand for: a type of unsigned integer of length 8 bits OR unsigned integer of length 8 bits (note the underlined characters)

Comments welcome

Delta_G

int is a type that is defined as different lengths on different systems.  One the AVR Arduinos like UNO and Mega it is 16 bits.  On a Due it's 32 bits.  On your computer it might be 64 bits. 

There are another way to refer to types.  int8_t or int16_t mean signed integers 8 or 16 bits wide.  They're always that wide, no matter what processor you use them on.  With a u in front they're unsigned.  So uint8_t is the same as an 8 bit unsigned byte.  The uint16_t would be the same as unsigned int on an UNO.  But it's half the size of unsigned int on a Due. 

The point of those is that you always know exactly how big they are. 
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

marco_c

Just using int causes a huge number of issues when you move from one architecture to another, as the size of int is usually defined as the 'natural' size for the architecture. This makes it 8 bits for 8 bit architectures, 16 for 16, etc. What you think you see is not what you get. Moving from a 32 to 16 bit architecture can break a lot of code with no apparent reason behind it. The same goes for long type.

The use of the uintxx_t type ensures that you always get the same size of integer and your code will always work the same no matter where it is run.

Personally, I find it frustrating that the Arduino examples still use int, as this is a bad habit left over from the 'C' days, and it is not teaching the new generation of programmers good habits from the start.
Arduino Libraries https://github.com/MajicDesigns?tab=Repositories
Parola for Arduino https://github.com/MajicDesigns/Parola
Arduino++ blog https://arduinoplusplus.wordpress.com

GolamMostafa

#3
Mar 09, 2018, 05:29 am Last Edit: Mar 09, 2018, 07:40 am by GolamMostafa
Quote
int is a type that is defined as different lengths on different systems.  One the AVR Arduinos like UNO and Mega it is 16 bits.  On a Due it's 32 bits.  On your computer it might be 64 bits.  
The following declaration : int x = 0x12345678; is compiled/uploaded into Arduino DUE Board without any trouble. But, the mind-set is heavily confused as we have been all along, in the Arduino Platform, declaring the data types as per prescription of the Arduino Programming Reference Manual where it has been stated:

int : 16-bit
long : 32-bit  

bperrybap

#4
Mar 09, 2018, 07:45 am Last Edit: Mar 09, 2018, 07:49 am by bperrybap
Just using int causes a huge number of issues when you move from one architecture to another, as the size of int is usually defined as the 'natural' size for the architecture. This makes it 8 bits for 8 bit architectures, 16 for 16, etc.
The C standard has required the minimum size of an int be 16 bits for many decades.
So there is no C implementation where an int is 8 bits.
(I saw one for the 6502 back in the very early 80's but those days are long past...)

To the OP,
The stdint types (which is what we are talking about) were formalized in the C standard about 20 years ago.
Prior to that you had to play games and define your own types to get known sizes for your data types.

These days, if size matters, then you should not use native data types and use types from stdint.
When size doesn't matter, and the value is known to fit in 16 bits then int is normally used.
I say normally because this doesn't really hold for the AVR.
The AVR has many issues when it comes to C.
One area is the native size since it really is an 8 bit processor, but because C limits an int to be no smaller than 16 bits, an int is 16 bits on the AVR. So while the AVR is only 8 bits, it must act like a 16 bit processor.
Because the AVR is only an 8 bit processor ints are much less efficient than char (8 bit) types.
And THAT is why you often see uint8_t or int8_t used in Arduino code.
It is much more efficient in terms of code, timing, and space to use 8 bit variables rather than 16 bit variables on the AVR.

However, the reverse can also happen.
i.e. if you define something as uint8_t it may be more efficient on the AVR but less efficient on other processors that may have to do lots of masking on the register contents to ensure that the registers upper bits are never set.

stdint also has a solution to help with that as well.
they are the "least" types.
i.e.
uint_least8_t
uint_least16_t

When code is used across diverse platforms, these can be a better choice for certain things like loops as it ensures it to be at least the minimum number of bits but allows it to be larger if that is more efficient for the target processor.
For things like loops this would be the ideal choice as it gives you a loop variable that is most efficient for the processor that is large enough to hold the needed values.

--- bill







cheche_romo

its a data type uint stands for unsigned int and it means that it can store 2^n different values from 0 to 2^n - 1, n being the number in the data type for example uint8_t stores values from 0 to 255.

if is a signed datatype it means the the variable can also store negative numbers so a uint8_t is the same size as a int8_t, the difference is the signed variable stores values from -127 to 127.

GolamMostafa

#6
Mar 09, 2018, 10:42 am Last Edit: Mar 09, 2018, 11:02 am by GolamMostafa
Quote
if is a signed datatype it means the the variable can also store negative numbers so a uint8_t is the same size as a int8_t, the difference is the signed variable stores values from -127 to 127.
The 8-bit variable (assume that the result is in 2's complement form) can be populated with bit pattern as follows:

0 0000000   ----> 0
---------------------
0 1111111  ----> +127
--------------------
1 0000000  ----> -128  (MS-bit carries negative positional value = -1x27 under condition that it is not an overflow bit.)
-------------------------
1 1111111  ----> -1 (in 2's complement form all bits carry positive positional values except the MS-bit)

So, the range : - 128 to +127

oqibidipo

The C standard has required the minimum size of an int be 16 bits for many decades.
So there is no C implementation where an int is 8 bits.
(I saw one for the 6502 back in the very early 80's but those days are long past...)
You can make avr-gcc use 8-bit ints with the -mint8 option, but that makes it nonstandard.

Quote
However, the reverse can also happen.
i.e. if you define something as uint8_t it may be more efficient on the AVR but less efficient on other processors that may have to do lots of masking on the register contents to ensure that the registers upper bits are never set.

stdint also has a solution to help with that as well.
they are the "least" types.
i.e.
uint_least8_t
uint_least16_t

When code is used across diverse platforms, these can be a better choice for certain things like loops as it ensures it to be at least the minimum number of bits but allows it to be larger if that is more efficient for the target processor.
uint_leastN_t is the smallest type that can hold at least N bits and very likely the same type as uintN_t when uintN_t is defined.
What you are describing is uint_fastN_t.

oqibidipo

if is a signed datatype it means the the variable can also store negative numbers so a uint8_t is the same size as a int8_t, the difference is the signed variable stores values from -127 to 127.
The 8-bit variable (assume that the result is in 2's complement form)
There's no need to assume, intN_t uses 2's complement by definition, so int8_t range is -128 to 127.

int_leastN_t and int_fastN_t do not have to use 2's complement for negative values.

Go Up