# Difference between char and uint8\_t

**URL:** <https://forum.arduino.cc/t/difference-between-char-and-uint8-t/1146101>\
**Category:** Programming\
**Created:** [July 9, 2023, 2:40am UTC](https://forum.arduino.cc/t/difference-between-char-and-uint8-t/1146101 "2023-07-09T02:40:49Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![stitech](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/stitech/32/1016377_2.png) [@stitech](https://forum.arduino.cc/u/stitech)\
**Post date:** [July 9, 2023, 5:38am UTC](https://forum.arduino.cc/t/difference-between-char-and-uint8-t/1146101/25 "2023-07-09T05:38:51Z")

</div>

I am learning C and C++. That's how I came across the warning in post #1.

And as for Nano Every or UNO R3: the instruction set is almost identical. The main difference is in the registers.

By now the question from post #1 has been answered: char is a signed number and byte is unsigned. I now expect functions like Serial.print to react the same to int8\_t as to char, and uint8\_t the same as byte. I will keep using int8\_t and uint8\_t because the names are less confusing.

This discussion has clarified quite a bit, thank you all.

---

<div class="post-metadata">

**Author:** ![GolamMostafa](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/golammostafa/32/239011_2.png) [@GolamMostafa](https://forum.arduino.cc/u/GolamMostafa)\
**Post date:** [July 9, 2023, 6:21am UTC](https://forum.arduino.cc/t/difference-between-char-and-uint8-t/1146101/26 "2023-07-09T06:21:37Z")

</div>

> [@stitech](#):
>
> I will keep using int8\_t and uint8\_t because the names are less confusing.

But, they are less common. In Arduino Forum, most of the users/learners have Arduino UNO and they mostly use the following data types:

```arduino
char (range: 0x80 - 0x7F = -128 to +127)
byte (range: 0x00 - 0xFF = 0 - 255)
int (range: 0x8000 - 0x7FFF = -32768 to 32767)
unsigned int (range: 0x0000 - 0xFFFF = 0 to 65535)
long int (range: 0x80000000 - 0x7FFFFFFF = -2147483648 to 2147483647)
unsignd long int (range: 0x00000000 - 0xFFFFFFFF = 0 to 4294967295)
float (range: ?)
bool (range: true - false)

```

---

<div class="post-metadata">

**Author:** ![jfjlaros](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/jfjlaros/32/716915_2.png) [@jfjlaros](https://forum.arduino.cc/u/jfjlaros)\
**Post date:** [July 9, 2023, 6:32am UTC](https://forum.arduino.cc/t/difference-between-char-and-uint8-t/1146101/27 "2023-07-09T06:32:51Z")

</div>

> [@JCA34F](#):
>
> char is an 8 bit **signed** variable

It is a distinct type.

> [@](#):
>
> [Character types](https://en.cppreference.com/w/cpp/language/types#Character_types)
> 
> char — type for character representation which can be most efficiently processed on the target system (has the same representation and alignment as either signed char or unsigned char, but is always a distinct type).

---

<div class="post-metadata">

**Author:** ![stitech](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/stitech/32/1016377_2.png) [@stitech](https://forum.arduino.cc/u/stitech)\
**Post date:** [July 9, 2023, 7:03am UTC](https://forum.arduino.cc/t/difference-between-char-and-uint8-t/1146101/28 "2023-07-09T07:03:22Z")

</div>

Aaaaand… the confusion is back. Type char can be signed or unsigned.  
"…most efficiently processed on the target system" may include EBCDIC and such.

The system to which int8\_t and others belong, was invented to end the ambiguity of the old system with int and long a.o.  
Aaaaand… Arduino translates it back! typedef` ` uint8\_t` ` byte`;` means that when I declare a variable uint8\_t, the compiler reads byte before compiling.

---

<div class="post-metadata">

**Author:** ![stitech](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/stitech/32/1016377_2.png) [@stitech](https://forum.arduino.cc/u/stitech)\
**Post date:** [July 9, 2023, 7:14am UTC](https://forum.arduino.cc/t/difference-between-char-and-uint8-t/1146101/31 "2023-07-09T07:14:08Z")

</div>

typedef volatile uint8\_t register8\_t;  
#define CCP \_SFR\_MEM8(0x0034) /\* Configuration Change Protection \*/  
(from: avr/iom4809.h)

If the typedef works backwards from other defines: Oh joy! More confusion.

```arduino
#define ledPin 3

```

(from: Arduino Reference)

---

<div class="post-metadata">

**Author:** ![oqibidipo](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/oqibidipo/32/221794_2.png) [@oqibidipo](https://forum.arduino.cc/u/oqibidipo)\
**Post date:** [July 9, 2023, 10:50am UTC](https://forum.arduino.cc/t/difference-between-char-and-uint8-t/1146101/32 "2023-07-09T10:50:54Z")

</div>

> [@Delta\_G](#):
>
> It's always signed on Arduino

Nope.  
AVR: signed  
ARM: unsigned (\*)  
ESP8266, ESP32: unsigned

(\*) except Arduino Renesas cores (Uno R4, Portenta C33) which have `-fsigned-char` in compiler flags

---

<div class="post-metadata">

**Author:** ![alto777](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/alto777/32/317385_2.png) [@alto777](https://forum.arduino.cc/u/alto777)\
**Post date:** [July 9, 2023, 12:05pm UTC](https://forum.arduino.cc/t/difference-between-char-and-uint8-t/1146101/33 "2023-07-09T12:05:18Z")

</div>

> [@stitech](#):
>
> Char myVal = 0x41;
> 
> myVal \*= 3;
> 
> Prints: -109 or 0xFFFFFF93

No it doesn't. There is no Char type. Post the entire sketch.

-109 in decimal is 0x93 in hex, which in a signed byte is how you store… -109.

To get the negative representation of a number, flip all the bits and add 1.

Don't take my word for it: [Negate binary nmber](https://en.wikipedia.org/wiki/Two%27s_complement)

109 is 0x6d.

01101101 in binary, to negate, flip the bits and add one  
10010010  
00000001 =

10010011, or 0x93.

Now that I've typed all this, it looks like _you_ were the one who turned it into a 32 bit number. Did you happen to use an on line calculator? The step you forget was to chop your result down to 8 bits one byte which is all you have.

HTH

a7

---

<div class="post-metadata">

**Author:** ![JCA34F](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/jca34f/32/340148_2.png) [@JCA34F](https://forum.arduino.cc/u/JCA34F)\
**Post date:** [July 9, 2023, 1:03pm UTC](https://forum.arduino.cc/t/difference-between-char-and-uint8-t/1146101/34 "2023-07-09T13:03:02Z")

</div>

Guess I should have specified Arduino Nano with AtMega 328P and IDE 1.8.5. 🙄

---

<div class="post-metadata">

**Author:** ![stitech](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/stitech/32/1016377_2.png) [@stitech](https://forum.arduino.cc/u/stitech)\
**Post date:** [July 9, 2023, 1:48pm UTC](https://forum.arduino.cc/t/difference-between-char-and-uint8-t/1146101/35 "2023-07-09T13:48:45Z")

</div>

[alto777](https://forum.arduino.cc/u/alto777), if you want the complete sketch, see post#21.  
There is a possibility that the extra Fs were added in my computer, not in the board.

[JCA34F](https://forum.arduino.cc/u/JCA34F), know the difference between the Nano and the Nano Every.  
To accomodate for the boards I have, Arduino decided to load versions 1.8.6 and 1.8.8, not 1.8.5.  
I still have 5 versions of arduino.h on my computer.

---

<div class="post-metadata">

**Author:** ![david\_2018](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/david_2018/32/1013044_2.png) [@david\_2018](https://forum.arduino.cc/u/david_2018)\
**Post date:** [July 9, 2023, 2:01pm UTC](https://forum.arduino.cc/t/difference-between-char-and-uint8-t/1146101/36 "2023-07-09T14:01:14Z")

</div>

> [@stitech](#):
>
> I now expect functions like Serial.print to react the same to int8\_t as to char, and uint8\_t the same as byte.

Not quite. Serial.print() will print a char as an ASCII character, while an int8\_t will print as an integer number.

---

<div class="post-metadata">

**Author:** ![stitech](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/stitech/32/1016377_2.png) [@stitech](https://forum.arduino.cc/u/stitech)\
**Post date:** [July 9, 2023, 2:13pm UTC](https://forum.arduino.cc/t/difference-between-char-and-uint8-t/1146101/37 "2023-07-09T14:13:02Z")

</div>

So it comes down to: push a button and see what happens.

Apparently the problem is me, because I like to know what, when, where and why, preferrably before I push the button.

In the end it means: testing, testing, testing.

---

<div class="post-metadata">

**Author:** ![build\_1971](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/build_1971/32/689930_2.png) [@build\_1971](https://forum.arduino.cc/u/build_1971)\
**Post date:** [July 9, 2023, 5:17pm UTC](https://forum.arduino.cc/t/difference-between-char-and-uint8-t/1146101/39 "2023-07-09T17:17:16Z")

</div>

Is it really that important whether char is signed or unsigned?  
You are supposed to use it to store characters...  
And you can use the fact that they are represented as a number to sort characters alphabetically...  
Why would you do a calculation that causes an overflow?

---

<div class="post-metadata">

**Author:** ![noiasca](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/noiasca/32/1126910_2.png) [@noiasca](https://forum.arduino.cc/u/noiasca)\
**Post date:** [July 10, 2023, 7:57am UTC](https://forum.arduino.cc/t/difference-between-char-and-uint8-t/1146101/40 "2023-07-10T07:57:36Z")

</div>

> [@build\_1971](#):
>
> Is it really that important whether char is signed or unsigned?

just if you claim in a forum post that it would be the same but it isn't.

Back in the days I had an perfect working sketch for an Uno which misbehaved on an ESP8266. Root cause ... the different char representation.

---

<div class="post-metadata">

**Author:** ![stitech](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/stitech/32/1016377_2.png) [@stitech](https://forum.arduino.cc/u/stitech)\
**Post date:** [July 10, 2023, 10:17pm UTC](https://forum.arduino.cc/t/difference-between-char-and-uint8-t/1146101/41 "2023-07-10T22:17:15Z")

</div>

> [@build\_1971](#):
>
> Why would you do a calculation that causes an overflow?

In post#21 I did it just to see what happens.  
But it happens all the time. This is part of the initializing routine of Arduino IDE.

 ![Schermopname (24)](https://europe1.discourse-cdn.com/arduino/original/4X/2/0/4/204dffe4bda2268360349df453a0912ebf56aa79.png)

---

<div class="post-metadata">

**Author:** ![jfjlaros](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/jfjlaros/32/716915_2.png) [@jfjlaros](https://forum.arduino.cc/u/jfjlaros)\
**Post date:** [July 11, 2023, 5:22pm UTC](https://forum.arduino.cc/t/difference-between-char-and-uint8-t/1146101/42 "2023-07-11T17:22:40Z")

</div>

> [@stitech](#):
>
> I did it just to see what happens.

Overflow of a `char` is not defined, so anything can happen.

---

<div class="post-metadata">

**Author:** ![christop](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/christop/32/1013044_2.png) [@christop](https://forum.arduino.cc/u/christop)\
**Post date:** [July 11, 2023, 5:33pm UTC](https://forum.arduino.cc/t/difference-between-char-and-uint8-t/1146101/43 "2023-07-11T17:33:08Z")

</div>

> [@Delta\_G](#):
>
> > [@stitech](#):
> >
> > Aaaaand… the confusion is back. Type char can be signed or unsigned.
> 
> It's always signed on Arduino. But it can be different on different systems. It can even be 16 bits.

I believe some Arduino platforms treat `char` as unsigned by default. e.g., Arduino Due.

Oops, oqibidipo already mentioned that. It would help if I read the whole thread before posting. 🤦‍♂️

---

<div class="post-metadata">

**Author:** ![GolamMostafa](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/golammostafa/32/239011_2.png) [@GolamMostafa](https://forum.arduino.cc/u/GolamMostafa)\
**Post date:** [July 12, 2023, 4:00am UTC](https://forum.arduino.cc/t/difference-between-char-and-uint8-t/1146101/44 "2023-07-12T04:00:48Z")

</div>

> [@christop](#):
>
> I believe some Arduino platforms treat `char` as unsigned by default. e.g., Arduino Due.

Is it the DUE hardware or the Compiler that treats _char_ keyword as an unsigned data type? Compiler differs MCU to MCU; whereas, ALU circuit remains the same for all MCUs except the processing size.

---

<div class="post-metadata">

**Author:** ![stitech](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/stitech/32/1016377_2.png) [@stitech](https://forum.arduino.cc/u/stitech)\
**Post date:** [July 12, 2023, 4:50am UTC](https://forum.arduino.cc/t/difference-between-char-and-uint8-t/1146101/45 "2023-07-12T04:50:55Z")

</div>

It's the compiler.

A processor has no knowledge of the type of a variable. The compiler does. When moving data, the type is irrelevant. Neither when adding or subtracting. Things are different when multiplying or dividing. The AVR has different instructions for multiplication with signed and unsigned. The compiler needs to choose the right one. Thus `varC = varA * varB` will generate different machine code depending on signed or unsigned.

Also for comparison, the compiler needs to differentiate between Z, C, N, V and S statusbits and choose the right ones.

To make programs portable, higher languages (like C and C++) have been invented and rules for behavior of the compilers established. But as comprehensive these may be, some things fall between the cracks. Like the definition of `char`, apparently.

---

<div class="post-metadata">

**Author:** ![stitech](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/stitech/32/1016377_2.png) [@stitech](https://forum.arduino.cc/u/stitech)\
**Post date:** [July 12, 2023, 2:41pm UTC](https://forum.arduino.cc/t/difference-between-char-and-uint8-t/1146101/47 "2023-07-12T14:41:27Z")

</div>

[Delta\_G](https://forum.arduino.cc/u/Delta_G)  
If I read a typedef as a declaration instead of a #define, things make sense.  
In this case the colors do not help.

 ![Part of stdio](https://europe1.discourse-cdn.com/arduino/original/4X/9/b/2/9b2ab0a766195dd822f1fc6178b9209d3507bb4d.png)

---

<div class="post-metadata">

**Author:** ![PieterP](https://avatars.discourse-cdn.com/v4/letter/p/ecccb3/32.png) [@PieterP](https://forum.arduino.cc/u/PieterP)\
**Post date:** [July 12, 2023, 3:13pm UTC](https://forum.arduino.cc/t/difference-between-char-and-uint8-t/1146101/48 "2023-07-12T15:13:57Z")

</div>

> [@stitech](#):
>
> If the typedef works backwards from other defines: Oh joy! More confusion.

This is one of the reasons why you should not use `typedef`:  
[C++ Core Guidelines T.43: Prefer `using` over `typedef` for defining aliases](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#t43-prefer-using-over-typedef-for-defining-aliases)

```cpp
typedef uint8_t bad_byte;
using good_byte = uint8_t;

```

[Previous page](https://forum.arduino.cc/t/difference-between-char-and-uint8-t/1146101.md?page=1)

[Next page](https://forum.arduino.cc/t/difference-between-char-and-uint8-t/1146101.md?page=3)
