"Andy" <> wrote in message
news: om...
....
> Can unsigned short be more than 2 bytes long?
Yes. The only _size_ criteria is that sizeof(short) >= 1. Of course, it has
to satisfy the minimum range requirement [0..65535], so the size of a short
(and therefore unsigned short) must be at least 16 bits. But since CHAR_BIT
may be anything >= 8, like 16 or 32 (e.g. DSP chipsets often have
implementations where CHAR_BIT is 32), it is possible for sizeof(short) to
be 1.
Theoretically, sizeof(short) > sizeof(long) is allowed in a conforming
implementation without contradiction.
Basically, the byte size of unsigned short is totally irrelevent to the
issue. The semantics of C integer expressions are defined by type and value,
not by the size of the representations.
You would do well to avoid forming preconceptions about the size of various
integer types. Not because there are theoretical possibilities, but because
there are very real practical problems that can result as a consequence.
E.g., when the world went from 16 to 32-bit home computers an awful lot of
poor code had to be painstakingly rewritten. Now that we sit on the edge of
64-bit machines becoming the 'norm', you should appreciate that making
assumptions about integer sizes may cost you (or the people who have to
maintain your code) in a few years time.
> If not, then
> (unsigned short)c1 + (unsigned short)c2 will never cause undefined
> behavior because
> 1. If INT_MAX == USHRT_MAX, then c1 and c2 will be promoted
> to unsigned short and unsigned short additions will never
> cause undefined behaviors.
INT_MAX == USHRT_MAX is extremely unlikely[*], but in such a case, the
operands of + will both be promoted to int since all the values of unsigned
short _are_ representable as an int. The promotion to int applies to the
operands, which in this case are...
(unsigned short) c1 and (unsigned short) c2
A cast will not _override_ integral promotion.
> 2. If INT_MAX > USHRT_MAX, then c1 and c2 will be promoted to
> int, but c1+c2 is always <= 2*65535
Strictly speaking, in this case, the sum of two unsigned short values is
always less than or equal to 2*USHRT_MAX+1.
> so the addition can
> never overflow because INT_MAX is >= 4 bytes.
There is nothing in the standards that state that an int must be twice the
size of an unsigned short. There are plenty of implementations where short
and int have the same properties except for their 'rank'.
> So then is correct to say that (unsigned short)c1 + (unsigned short)c2
> will never cause undefined behaviors? The reason is because in the
> book "C, Traps and Pitfalls", the author states that unsigned arithmetic
> shall always be done modulus 2^n manner where n is the number of bits
> for the unsigned variable.
Yes, but you have to be careful to assertain whether the arithmetic is
indeed being performed on unsigned operands. In the case of adding two
unsigned short values, that isn't a given.
> But the edition I got is old (~1991) and
> predates the ANSI standard.
I've never read the book, but what it says is true. What the author may not
have known at the time of original writing was whether unsigned short would
possibly promote to int, instead of always promoting to unsigned int. [This
was apparently contested by the C committee.]
> How about (unsigned long)c1 + (unsigned long)c2?
The two operands have type unsigned long and are therefore not subject to
integral promotion, nor indeed any other promotion. So the result is an
unsigned long calculated modulo ULONG_MAX+1.
[*] C90 apparently has no concept of padded integers or integer trap
representations, so you're not likely to find a conforming C implementation
where INT_MAX == USHRT_MAX any time soon. It's possible in C99, but I doubt
anyone will ever actually build such an implementation. [It would be
possible on a machine which used floating point instructions to mimic
integer calculations, but such a machine would probably have a hard time
implementing unsigned integer types as a whole, so the compiler writers
would probably give it up as a bad job.

]
--
Peter