Explicit unsigned/signed conversion: ANSI/ISO rules?

K

Ken Tough

Seems like a simple thing to find out, but I'm struggling. I have
googled, but everything I find is about implicit conversion,
not explicit.

Is this implementation-specific, or does ANSI/ISO lay out what
should happen for:

--------------------------
signed char sc;
unsigned char uc;

uc = 0xFF;
sc = (signed char)uc;

[what value is now in sc? Will it always be -1? What about
non-two's complement representations, etc. I need to know
that coding is not implementation-specific.]
--------------------------

And similarly the case for
sc = -100;
uc = (unsigned char sc);

[what value is guaranteed to be uc?]
 
C

CBFalconer

Ken said:
Seems like a simple thing to find out, but I'm struggling.
I have googled, but everything I find is about implicit
conversion, not explicit.

Is this implementation-specific, or does ANSI/ISO lay out
what should happen for:

--------------------------
signed char sc;
unsigned char uc;

uc = 0xFF;
sc = (signed char)uc;

[what value is now in sc? Will it always be -1? What about
non-two's complement representations, etc. I need to know
that coding is not implementation-specific.]
--------------------------

And similarly the case for
sc = -100;
uc = (unsigned char sc);

[what value is guaranteed to be uc?]

All the answers are implementation specific, and are covered by
the values in <limits.h>. Look at CHAR_BIT, UCHAR_MAX, SCHAR_MAX,
SCHAR_MIN. On many systems those values will be 8, 255, 127,
-128, respectively, but that is far from guaranteed.
 
R

Robert Harris

Ken said:
Seems like a simple thing to find out, but I'm struggling. I have
googled, but everything I find is about implicit conversion,
not explicit.

Is this implementation-specific, or does ANSI/ISO lay out what
should happen for:

--------------------------
signed char sc;
unsigned char uc;

uc = 0xFF;
sc = (signed char)uc;

[what value is now in sc? Will it always be -1?
That depends on chars having 8 bits, which is not always true.
See section 6.2.6.2 of the C standard for a discussion of the
representation of negative integers and 6.3.1.3 for conversions between
negative signed integers and unsigned integers. According to my reading
of it, (signed char)0xFF will always be -1 for an 8-bit char.

Robert
 
E

Eric Sosman

Ken said:
Seems like a simple thing to find out, but I'm struggling. I have
googled, but everything I find is about implicit conversion,
not explicit.

Is this implementation-specific, or does ANSI/ISO lay out what
should happen for:

--------------------------
signed char sc;
unsigned char uc;

uc = 0xFF;
sc = (signed char)uc;

[what value is now in sc? Will it always be -1? What about
non-two's complement representations, etc. I need to know
that coding is not implementation-specific.]

The behavior is implementation-specific. To begin with,
implementations are free to use more than eight bits for a
`char' type, and some do. On such implementations it may be
the case that SCHAR_MAX is 255 or greater, and if so the
value stored in `sc' will be 255.

On implementations where SCHAR_MAX is less than 255, the
behavior is again implementation-specific, and there are two
broad classes of behavior. First, `sc' may receive some
implementation-defined value: -1, or 0, or 42, or your age
as of your grandmother's last birthday. Alternatively, the
implementation may "trap" the attempt to convert the out-of-
range value, raising an implementation-defined signal. What
happens next depends on whether you have installed a handler
for that signal, and on the implementation's rules for how
the signal is handled.

In short, although `sc = -1' is a common outcome it is
by no means guaranteed.
--------------------------

And similarly the case for
sc = -100;
uc = (unsigned char sc);

[what value is guaranteed to be uc?]

`UCHAR_MAX - 99', after repairing the syntax error.
 
R

Ralmin

Ken Tough said:
Seems like a simple thing to find out, but I'm struggling. I have
googled, but everything I find is about implicit conversion,
not explicit.

There is no semantic difference between implicit conversion and explicit
conversion. Both have exactly the same semantics (meaning and result).

The only language difference is that in some cases (especially conversions
involving pointers other than pointers to void) only explicit conversions
are allowed; implicit conversion would generate a constraint violation.

However, all types of signed and unsigned integers and floating-point values
can be implicitly converted. The addition of a cast is unnecessary.
Is this implementation-specific, or does ANSI/ISO lay out what
should happen for:

--------------------------
signed char sc;
unsigned char uc;

uc = 0xFF;
sc = (signed char)uc;

[what value is now in sc? Will it always be -1? What about
non-two's complement representations, etc. I need to know
that coding is not implementation-specific.]

If the signed char type has more than 8 value bits then the value in sc will
always be 255.

Otherwise, the signed char type has 8 value bits, the value is out of range,
and the resulting value is implementation-defined, or (in C99) the
conversion might cause an implementation-defined signal to be raised.

If the implementation takes the obvious easy option and does not change the
representation when converting from signed char to unsigned char, then the
result will be:
binary 11111111 is -1 in 2's complement
binary 11111111 is -0 in 1's complement. Negative zeros
might be silently changed back to normal zeros, or
they might be considered a valid value.
binary 11111111 is -127 in signed magnitude

Or, if the implementation decides to be perverse, it could define the result
in any way it chooses.

--------------------------

And similarly the case for
sc = -100;
uc = (unsigned char sc);

Typo: (unsigned char)sc;
[what value is guaranteed to be uc?]

The value of uc is guaranteed to be UCHAR_MAX - 99. That will be 156 on all
systems with an 8-bit byte. It could be 412 on a 9-bit byte, 65436 on a
16-bit byte, 4294967196 on a 32-bit byte, for example.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,135
Latest member
VeronaShap
Top