Arduino 1.0 beta print(uint8_t) vs print(int8_t) ??

Why does Arduino 1.0 beta1 Print treat “signed char”, and “unsigned char” in the new way?

For “signed char”, Print writes the byte as before.

For “unsigned char”, Print converts the byte to its ASCII decimal representation.

This code prints “A” in 0022 but prints “65” in Arduino 1.0 beta.

  unsigned char c = 'A';

From Print.h

    void print(char);
    void print(unsigned char, int = DEC);

In the C/C++ standard char can be signed or unsigned so it seems strange to treat them in such a different manner. Why add to the confusion already in C++.

The char type was a problem from the beginning of the C language. Kernighan and Ritchie allowed char to be used as a number but didn’t specify if it was signed or unsigned. They did specify an unsigned char.

After much confusion this was the compromise:

The comprimise was to make signed char a type distinct from the two existing character types, while requiring char to have the same representation and values as either signed char or unsigned char. In other words, a char must look exactly like a signed char or unsigned char to the hardware; which one is implementation-defined. C++ later adopted this compromise for compatibility with C, so both languages now have three distinct char types.

Why does Arduino 1.0 beta1 Print treat "signed char", and "unsigned char" in the new way?

I suspect this is the reasoning...

unsigned char (aka uint8_t, byte) is often used instead of int to store small range numbers. signed char (aka char) is typically used to store a single text character.

So, the typical user probably wants unsigned char to be treated the same as int but signed char to be treated as a text character.

Why add to the confusion already in C++.

I believe the goal is to reduce the confusion for new users. In the Arduino world, byte is for storing numbers, char is for storing text.

I keep forgetting the “Arduino Language” is not C++.

Changing the behavior print(uint8_t) and not print(int8_t) seems strange but then much of the “Arduino Language” seems strange to me.

The standard for C++ says I/O operators treat char, signed char, and, unsigned char in the same way.

So these all put a single byte in the output stream.

  ostream& operator<< (ostream& out, char c );
  ostream& operator<< (ostream& out, signed char c );
  ostream& operator<< (ostream& out, unsigned char c );

The same holds for other character definitions. For example:

A character sequence is an array object (8.3.4) A that can be declared as T A[N ], where T is any of the types char, unsigned char, or signed char (3.9.1), optionally qualified by any combination of const or volatile.

Looks like the properties of the char type confuses Coding Badly also.

Let explain char again and give an example.

For the C/C++ types, short, int, long, and long long, you can only have two overloaded print functions. If T is one of these types "signed T" is the same type as T.

For char there are three distinct types. The Arduino print class only has print functions for two types, char and unsigned char. The type int8_t, signed char, is not specified so the compiler picks print(char) during overload resolution.

If you are going to make print(uint8_t) format a number why not also make print(int8_t) format a number. print(char) would call write() to output its argument as a single byte.

Here is an example that proves there can be three overloaded functions for the char type:

// C++ has three char types unlike short, int, and, long
// which have two types

void demo(char c) {Serial.println(c);}

void demo(int8_t c) {Serial.println(c, DEC);}

void demo(uint8_t c) {Serial.println(c, DEC);}

void setup() {
  char c1 = 'A';
  int8_t c2 = -12;
  uint8_t c3 = 34;
void loop() {}

This example prints:

A -12 34