Ben Bacarisse
5/9/2011 12:56:00 PM
Shao Miller <sha0.miller@gmail.com> writes:
> John wrote:
>> This is not a homework problem.
>>
>> So the problem requires me to compute a checksum in a signed char variable that is initialized to -1. As each character is read...it is added to the checksum. Any overflow from the checksum variable is ignored.
>
> I think that an addition expression involving 'signed char' can
> overflow if the addition exceeds 'SCHAR_MAX'. I'm not sure about a
> standard way to tell the compiler "ignore overflow for a 'signed char'
> addition."
That's not quite correct -- at least it glosses of over some important
details. Technically, an addition expression involving signed char
can't overflow because it can't happen -- the operands will be promoted
in to int. Of course, in the slightly odd (but not at all unheard of)
situation where char and int are the same size, the effect is as you
describe, only using INT_MAX rather than SCHAR_MAX.
However, in the much more common situation where char is much smaller
than int, the addition can not overflow. What goes wrong is the
conversion of the result back to signed char. This is not undefined
behaviour even when the value is too large. It's very close to UB
(from a portability point of vew) but it is implementation defined.
> If you are using getchar(), I think that's like using getc(stdin),
> which I think is fairly similar to using fgetc(stdin). Since fgetc()
> gets an 'unsigned char' and then converts it to an 'int' and returns
> that, perhaps the problem you are dealing with actually includes:
>
> "Compute a checksum using an 'unsigned char' object where that object
> is initialized to all-bits-set (all one bits for the value bits),
> which happens to be the two's complement representation for -1."
>
> I think that an addition expression involving 'unsigned char' cannot
> overflow, so your "ignored" criteria would be satisifed by using that
> type, instead.
Yes, but only for the technical reason that the operands will promote,
so there is no actual addition using unsigned char. unsigned char will
most often promote to int, and this can overflow in some outlandish
cases (imagine 16 bit ints and 15 bit chars). The most portable
solution is to convert (with a cast) the unsigned chars to unsigned int.
The arithmetic then won't overflow (let's ignore the terrible corner
case where unsigned int promotes to int!) and the conversion back to
unsigned char is well-defined.
<snip>
--
Ben.