Consider the following code :
#include <iostream> #include <type_traits> int main(int argc, char* argv[]) { std::cout<<"std::is_same<int, int>::value = "<<std::is_same<int, int>::value<<std::endl; std::cout<<"std::is_same<int, signed int>::value = "<<std::is_same<int, signed int>::value<<std::endl; std::cout<<"std::is_same<int, unsigned int>::value = "<<std::is_same<int, unsigned int>::value<<std::endl; std::cout<<"std::is_same<signed int, int>::value = "<<std::is_same<signed int, int>::value<<std::endl; std::cout<<"std::is_same<signed int, signed int>::value = "<<std::is_same<signed int, signed int>::value<<std::endl; std::cout<<"std::is_same<signed int, unsigned int>::value = "<<std::is_same<signed int, unsigned int>::value<<std::endl; std::cout<<"std::is_same<unsigned int, int>::value = "<<std::is_same<unsigned int, int>::value<<std::endl; std::cout<<"std::is_same<unsigned int, signed int>::value = "<<std::is_same<unsigned int, signed int>::value<<std::endl; std::cout<<"std::is_same<unsigned int, unsigned int>::value = "<<std::is_same<unsigned int, unsigned int>::value<<std::endl; std::cout<<"----"<<std::endl; std::cout<<"std::is_same<char, char>::value = "<<std::is_same<char, char>::value<<std::endl; std::cout<<"std::is_same<char, signed char>::value = "<<std::is_same<char, signed char>::value<<std::endl; std::cout<<"std::is_same<char, unsigned char>::value = "<<std::is_same<char, unsigned char>::value<<std::endl; std::cout<<"std::is_same<signed char, char>::value = "<<std::is_same<signed char, char>::value<<std::endl; std::cout<<"std::is_same<signed char, signed char>::value = "<<std::is_same<signed char, signed char>::value<<std::endl; std::cout<<"std::is_same<signed char, unsigned char>::value = "<<std::is_same<signed char, unsigned char>::value<<std::endl; std::cout<<"std::is_same<unsigned char, char>::value = "<<std::is_same<unsigned char, char>::value<<std::endl; std::cout<<"std::is_same<unsigned char, signed char>::value = "<<std::is_same<unsigned char, signed char>::value<<std::endl; std::cout<<"std::is_same<unsigned char, unsigned char>::value = "<<std::is_same<unsigned char, unsigned char>::value<<std::endl; return 0; }
The result is :
std::is_same<int, int>::value = 1 std::is_same<int, signed int>::value = 1 std::is_same<int, unsigned int>::value = 0 std::is_same<signed int, int>::value = 1 std::is_same<signed int, signed int>::value = 1 std::is_same<signed int, unsigned int>::value = 0 std::is_same<unsigned int, int>::value = 0 std::is_same<unsigned int, signed int>::value = 0 std::is_same<unsigned int, unsigned int>::value = 1 ---- std::is_same<char, char>::value = 1 std::is_same<char, signed char>::value = 0 std::is_same<char, unsigned char>::value = 0 std::is_same<signed char, char>::value = 0 std::is_same<signed char, signed char>::value = 1 std::is_same<signed char, unsigned char>::value = 0 std::is_same<unsigned char, char>::value = 0 std::is_same<unsigned char, signed char>::value = 0 std::is_same<unsigned char, unsigned char>::value = 1
Which means that int
and signed int
are considered as the same type, but not char
and signed char
. Why is that ?
And if I can transform a char
into signed char
using make_signed
, how to do the opposite (transform a signed char
to a char
) ?
You would use a signed char when you need to represent a quantity in the range [-128, 127] and you can't (for whatever reason) spare more than a single byte to do it.
An unsigned type can only represent postive values (and zero) where as a signed type can represent both positive and negative values (and zero). In the case of a 8-bit char this means that an unsigned char variable can hold a value in the range 0 to 255 while a signed char has the range -128 to 127.
Maximum value of signed char in C++It is generally used to store 8-bit characters. Being a signed data type, it can store positive values as well as negative values. Size of 8 bits is occupied where 1 bit is used to store the sign of the value.
In the book "Complete Reference of C" it is mentioned that char is by default unsigned.
It's by design, C++ standard says char
, signed char
and unsigned char
are different types. I think you can use static cast for transformation.
There are three distinct basic character types: char, signed char and unsigned char. Although there are three character types, there are only two representations: signed and unsigned. The (plain)char uses one of these representations. Which of the other two character representations is equivalent to char depends on the compiler.
In an unsigned type, all the bits represent the value. For example, an 8-bit unsigned char can hold the values from 0 through 255 inclusive.
The standard does not define how signed types are represented, but does specify that the range should be evenly divided between positive and negative values. Hence an 8-bit signed char is guaranteed to be able to hold values from -127 through 127.
So how to decide which Type to use?
Computations using char are usually problematic. Char is by default signed on some machines and unsigned on others. So we should not use (plain)char in arithmetic expressions. Use it only to hold characters. If you need a tiny integer, explicitly specify either signed char or unsigned char.
Excerpts taken from C++ Primer 5th edition, p. 66.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With