I guess the meaning of your question is what is key. When you say loss, you mean that you are losing bytes or something like that. You are not losing anything as such since the size of both are the same, they just have different ranges.
signed char and unsigned char are not guaranteed to be equal. When most people think unsigned char, they are thinking from 0 to 255.
On most implementations (I have to caveat because there is a difference), signed char and unsigned char are 1 byte or 8 bits. signed char is typically from -128 to +127 whereas unsigned char is from 0 to +255.
As far as conversions, it is left up to different implementations to come up with an answer. On a whole, I wouldn't recommend you converting between the two. To me, it makes sense that it should give you the POSITIVE equivalent if the value is negative and remain the same if is positive. For instance in Borland C++ Builder 5, given a signed char test = -1
and you cast it into unsigned char
, the result will be 255. Alternatively, the result is different if all values are positive.
But as far as comparisons, while the values may appear the same, they probably won't be evaluated as equal. This is a major trip up when programmers sometimes compare signed and unsigned values and wonder why the data all looks the same, but the condition will not work properly. A good compiler should warn you about this.
I'm of the opinion that there should be an implicit conversion between the signed and unsigned so that if you cast from one to the other, the compiler will take care of the conversion for you. It is up to the compiler's implementation on whether you lose the original meaning. Unfortunately there is no guarantee that it will always work.
Finally, from the standard, there should exist a plain conversion between signed char or unsigned char to char. But whichever it chooses to take, is implementation defined
3.9.1 Fundamental types [basic.fundamental]
1 Objects declared as characters char)
shall be large enough to store any
member of the implementation's basic
character set. If a character from
this set is stored in a character
object, the integral value of that
character object is equal to the value
of the single character literal form
of that character. It is
implementation-defined whether a char
object can hold negative values.
Characters can be explicitly declared
unsigned or signed. Plain char, signed
char, and unsigned char are three
distinct types. A char, a signed char,
and an unsigned char occupy the same
amount of storage and have the same
alignment requirements (basic.types);
that is, they have the same object
representation. For character types,
all bits of the object representation
participate in the value
representation. For unsigned character
types, all possible bit patterns of
the value representation represent
numbers. These requirements do not
hold for other types. In any
particular implementation, a plain
char object can take on either the
same values as a signed char or an
unsigned char; which one is
implementation-defined.