Difference between char and uint8_t

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.

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

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)

It is a distinct type.

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.

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.

#define ledPin 3

(from: Arduino Reference)

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

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

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

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

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

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, 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.

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

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.

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?

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.

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.

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

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. :man_facepalming:

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.

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.

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.

This is one of the reasons why you should not use typedef:
C++ Core Guidelines T.43: Prefer using over typedef for defining aliases

typedef uint8_t bad_byte;
using good_byte = uint8_t;