Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

integer promotion and arithmetic conversion

2 views
Skip to first unread message

sarathy

unread,
Aug 16, 2006, 12:37:33 AM8/16/06
to
Hi,
What is integer promotion? How is it different from
arithmetic conversion?

Regards,
Sarathy

Ark

unread,
Aug 16, 2006, 2:40:40 AM8/16/06
to
AFAIK, integer promotion refers specifically to integer types
participating in a binary operation (read: sub-expression) where the
types of operands must be identical (+ - * / % | ^ &).
E.g.,
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
etc.
signed promotion is value-preserving; promotion to an unsigned type
preserves the bit pattern.
Additionally, everything in an expression is promoted to at least int:
c+s means (int)c+(int)s
(I believe, in the old days it was not NECESSARILY true and was
implementation-defined.) E.g., on a typical 32-bit machine
unsigned short s = 0x1000U;
.....
s<<4 means ((int)s)<<4, i.e., 0x10000, not a short value.

These rules are made so that C programmers capable of writing robust
arithmetic expressions (or better yet, portable ones) could command big
bucks :)

Michael Mair

unread,
Aug 16, 2006, 3:29:02 PM8/16/06
to
sarathy schrieb:

> Hi,
> What is integer promotion? How is it different from
> arithmetic conversion?

I just gave a very loose explanation in
<4kh9lgF...@individual.net>
As this is IMO one of the topics that are presented rather
readable in the standard text, I suggest that you have a look
at "n1124.pdf" (just google for it), section 6.3.
Note that this is the current C99 standard plus technical
corrigenda -- C90 did behave a little bit different when it
came to the usual arithmetic conversions for operations involving
floating point operands and had no long long type.

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.

pete

unread,
Aug 16, 2006, 9:41:08 PM8/16/06
to
Ark wrote:
>
> sarathy wrote:
> > Hi,
> > What is integer promotion? How is it different from
> > arithmetic conversion?
> >
> > Regards,
> > Sarathy
> >
> AFAIK, integer promotion refers specifically to integer types
> participating in a binary operation (read: sub-expression) where the
> types of operands must be identical (+ - * / % | ^ &).
> E.g.,
> 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)

That's not what integer promotion is.
Integer promotion can only result in an expression
of either type int or type unsigned.

sizeof(c + c) == sizeof(u)

--
pete

Ark

unread,
Aug 16, 2006, 10:42:29 PM8/16/06
to
You are correct of course:
6.3.1.1
The following may be used in an expression wherever an int or unsigned
int may be used:
— An object or expression with an integer type whose integer conversion
rank is less than or equal to the rank of int and unsigned int.
— A bit-field of type _Bool, int, signed int, or unsigned int.
If an int can represent all values of the original type, the value is
converted to an int;
otherwise, it is converted to an unsigned int. These are called the
integer promotions.48) All other types are unchanged by the integer
promotions.

48) The integer promotions are applied only: as part of the usual
arithmetic conversions, to certain
argument expressions, to the operands of the unary +, -, and ~
operators, and to both operands of the
shift operators, as specified by their respective subclauses.

Chris Torek

unread,
Aug 20, 2006, 4:50:51 AM8/20/06
to
In article <DIudnYwGh6p7IH_Z...@comcast.com>

Ark <akh...@macroexpressions.com> wrote:
>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.

ena8...@yahoo.com

unread,
Aug 23, 2006, 11:03:49 PM8/23/06
to

This explanation is quite good, but I have a quibble.
For promotions, there is a notion of widening. For
binary operators though, both operand types participate
in finding a common real type and both operand values
are converted to that type. It isn't that we "widen"
one type and convert the other - both operands are
simply converted (and indeed no widening may take
place even when the conversion ranks are different).

Don't get me wrong, I like the explanation; I just
think it could be better if couched in language
more closely parallel to how language in the Standard
expresses it.

0 new messages