3

Why does the following code print "?" ? Also how can -1 be assigned to an unsigned char?

char test;
unsigned char testu; //isn't it supposed to hold values in range 0 - 255?
test = -1;
testu = -1;
cout<<"TEST CHAR = "<<test<<endl;
cout<<"TESTU CHAR = "<<testu<<endl;
Nemo
  • 4,601
  • 11
  • 43
  • 46

4 Answers4

13

unsigned simply affects how the internal representation of the number (chars are numbers, remember) is interpreted. So -1 is 1111 1111 in two's complement notation, which when put into an unsigned char changes the meaning (for the same bit representation) to 255.

The question mark is probably the result of your font/codepage not mapping the (extended) ASCII value 255 to a character it can display.

I don't think << discerns between an unsigned char and a signed char, since it interprets their values as ASCII codes, not plain numbers.

Also, it depends on your compiler whether chars are signed or unsigned by default; actually, the spec states there's three different char types (plain, signed, and unsigned).

Community
  • 1
  • 1
Cameron
  • 96,106
  • 25
  • 196
  • 225
  • 1
    `char` will behave like either `signed char` or like `unsigned char`, at the implementation's discretion, but is a separate type from whichever one it behaves like. Yes, this is exactly as much of a backwards-compatibility keep-everyone-happy hack (that actually probably causes problems for lots of people anyway) as it sounds like. – Karl Knechtel Sep 27 '11 at 08:34
4

When you assign a negative value to an unsigned variable, the result is that it wraps around. -1 becomes 255 in this case.

Vaughn Cato
  • 63,448
  • 5
  • 82
  • 132
  • Correct. Conversion of an integer to an unsigned type wraps around modulo 1 greater than the maximum value of the unsigned type. For a typical system with 8-bit bytes, it's reduced modulo 256 (UCHAR_MAX+1). – Keith Thompson Sep 27 '11 at 05:39
3

I don't know C or C++, but my intuition is telling me that it's wrapping -1 to 255 and printing ÿ, but since that's not in the first 128 characters it prints ? instead. Just a guess.

To test this, try assigning -191 and see if it prints A (or B if my math is off).

Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
  • 1
    What it prints depends on the locale. `ÿ` is character 255 in Unicode or Latin-1, but in UTF-8, for example, it has a multi-byte representation. – Keith Thompson Sep 27 '11 at 05:37
1

Signed/unsigned is defined by the use of the highest order bit of that number. You can assign a negative integer to it. The sign bit will be interpreted in the signed case (when you perform arithmetics with it). When you treat it it like a character it will simply take the highest order bit as if it was an unsigned char and just produce an ASCII char beyond 127 (decimal):

unsigned char c = -2;

is equivalent to:

unsigned char c = 128;

WHEN the c is treated as a character. -1 is an exception: it has all 8 bits set and is treated as 255 dec.

long404
  • 1,037
  • 9
  • 12