In article <DI******************************@comcast.com>

Ark <ak*****@macroexpressions.comwrote:

>char c;

short s;

unsigned u;

long l;

If I am not mistaken in this wee hour;

u+l means (long)u+l even if sizeof(unsigned)==sizeof(long)

s+u means (unsigned)s+u even if sizeof(unsigned)==sizeof(short)

c+s means (int)c+(int)s

Alas, you are mistaken. The ANSI/ISO rules are terribly complicated

by depending on the relative values of the corresponding MAXes.

Consider the "u+l" case for a moment. Suppose we are on a typical

32-bit machine, with 32-bit int and 32-bit long, and hence both

INT_MAX and LONG_MAX are 2147483647 while UINT_MAX is 4294967295.

The ANSI "value-preserving" rule says that widening a narrower

signed type produces a new, wider signed type if and only if the

relative *_MAX is not exceeded. Otherwise, it produces a new,

wider unsigned type.

Since UINT_MAX exceeds LONG_MAX, widen(u) produces unsigned long,

instead of signed long. We then have (unsigned long) + (signed long);

the second "signed" long is converted to "unsigned", and the addition

is done with unsigned arithmetic -- where overflow is discarded --

and the result has type "unsigned long".

If LONG_MAX is greater than UINT_MAX, however, widen(u) produces

signed long. We then have (signed long)+(signed long); the addition

is done in signed arithmetic (overflow giving undefined behavior)

and the result has type "signed long". This is the case on a

typical 64-bit machine (32-bit int, 64-bit long).

(See also the appended test code.)

>signed promotion is value-preserving;

This is correct: it preserves the value if possible (if the new

wider type has a lower *_MAX, we hit a snag; but this case is either

completely ruled out by the Standard, or else at least never seems

to occur in practice; I am not sure which). (C89 and C99 have

somewhat different wording, in part because C99 now has "long long"

as well.)

>promotion to an unsigned type preserves the bit pattern.

This is only true for two's complement systems. On a Univac, you

get some interesting code.

[test code]

#include <stdio.h>

long l;

unsigned u;

void f0(void) { if (u + l 0) puts("u + l is unsigned"); }

void f1(void) { if ((long)u + l 0) puts("(long)u + l is unsigned"); }

void f2(void) { if (u + (unsigned)l 0) puts("u + (unsigned)l is unsigned"); }

int main(void) {

u = -1U, l = -1L; /* -1L + -1L = -2L */

f0();

f1();

f2();

return 0;

}

--

In-Real-Life: Chris Torek, Wind River Systems

Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603

email: forget about it

http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.