David Wilkinson <no-reply@effisols.com> wrote:
Ulrich Eckhardt wrote:
[...]
Issue 1
-------
On Comeau, if I write
char c = char(1);
it compiles. But if I write
unsigned char uc = unsigned char(1); // 1
it does not. The same thing happens for other "compound types" like long
int. However, if I do
typedef unsigned char unsigned_char;
unsigned_char uc = unsigned_char(1); // 2
then it works. VC allows both 1 and 2, which seems correct to me.
I'm on Ulrich's side on this. I didn't even know VC would
accept this. I used to keep forgetting to put parentheses
around compund type names and various compilers barked at
me. (Nowadays I use the new cast syntax.) Also, IME, if VC
and Comeau disagree on something, I have never, ever found
Comeau to be wrong, but always VC.
Issue 2
-------
ostream::put() can only take a char as argument, so using it to output
an unsigned char is undefined behavior. This is why I switched to
operator << (which is overloaded for unsigned char). But what does it do?
'ostream::put()' is for unformatted output, 'operator<<()'
for formatted output.
In the VC source (in <ostream>) it just casts the unsigned char to char
(using a C-style cast), and then uses ostream::put() This works (for me)
on VC because 0xFF gives -1 when converted to char. But on some systems
(apparently) 0xFF converts to 127, which seems just crazy to me.
Whether 'char' is signed or unsigned is implementation-
defined.
I guess I didn't know that these compound names behaved differently. I
thought "unsigned char" was a single token. I thought I was "doing good"
by using constructor syntax rather than C-cast syntax, but I guess not.
As you say, static_cast is the way to go.
We are not talking about whether plain char is signed or not. We are
are "too big".