Discussion in 'C Programming' started by spibou@gmail.com, Aug 3, 2006.

1. ### Guest

On 6.3.1.1 of N1124 we read:

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.

A few lines above that we read:

The following may be used in an expres-
sion wherever an int or unsigned int may
be used:

So the first quote refers only to objects which can be
represented as an (unsigned) int , right ?

1. So why do integer promotion rules exist ?
(meaning before the first standard) implementations
promotion rules for situations where a type
smaller than int encountered across an operator
a type which was int. So the standard simply chose
between the 2 historical integer promotion practices.

2. Why do promotion rules apply when using the ~
operator ?

3. Which promotion rules apply when one of the
operands is (long) long (unsigned) int ?

Spiros Bousbouras

, Aug 3, 2006

2. ### =?utf-8?B?SGFyYWxkIHZhbiBExLNr?=Guest

wrote:
> On 6.3.1.1 of N1124 we read:
>
> 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.
>
> A few lines above that we read:
>
> The following may be used in an expres-
> sion wherever an int or unsigned int may
> be used:
>
> So the first quote refers only to objects which can be
> represented as an (unsigned) int , right ?

Yes.

> 1. So why do integer promotion rules exist ?

Because processors might not support arithmetic on char/short types.

> (meaning before the first standard) implementations
> had types smaller than int so they had to have *some*
> promotion rules for situations where a type
> smaller than int encountered across an operator
> a type which was int. So the standard simply chose
> between the 2 historical integer promotion practices.

What you describe now are called the "usual arithmetic conversions"
(6.3.1.8), not the "integer promotions".

> 2. Why do promotion rules apply when using the ~
> operator ?

The rules are consistent for mostly all operators, and for the unary -
operator, processors might not support arithmetic on char/short types.

> 3. Which promotion rules apply when one of the
> operands is (long) long (unsigned) int ?

With binary operators, it depends both on the other argument and their
ranges. With unary operators, there are no promotions.

=?utf-8?B?SGFyYWxkIHZhbiBExLNr?=, Aug 3, 2006

3. ### Eric SosmanGuest

wrote On 08/03/06 11:58,:
> On 6.3.1.1 of N1124 we read:
>
> 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.
>
> A few lines above that we read:
>
> The following may be used in an expres-
> sion wherever an int or unsigned int may
> be used:
>
> So the first quote refers only to objects which can be
> represented as an (unsigned) int , right ?
>
> 1. So why do integer promotion rules exist ?

struct {
int x : 7;
int y : 11;
} s = { 1, 2 };
int t = s.x + s.y;

Here we've got an expression that adds a seven-bit
integer and an eleven-bit integer. Flip through the
reference manuals for some of your favorite machines,
and see how many of them have an opcode that adds
operands of those two widths.

No luck? Then how is a C implementation supposed to
evaluate the sum? Software emulation of every operator
whose operands aren't identical and of "lucky" sizes?

C's answer is the integer promotions (more generally,
the "usual arithmetic promotions"), whose goal is to
arrive at a situation the machine can deal with easily.
So each of s.x and s.y gets promoted from its oddball
width to int, then the machine adds the two ints. With
the promotions, C needn't worry about all the possible
combinations of operand types for every operator; instead,
it just needs a way to move each type "up the ladder"
until the operator's operands match. Then C need only
describe how to add two ints, how to divide two doubles,
and so on: it doesn't need to define how to subtract
double from long double, double from double, double from
float, double from unsigned long long, ...

> (meaning before the first standard) implementations
> had types smaller than int so they had to have *some*
> promotion rules for situations where a type
> smaller than int encountered across an operator
> a type which was int. So the standard simply chose
> between the 2 historical integer promotion practices.
>
> 2. Why do promotion rules apply when using the ~
> operator ?

Because the Standard says so? How about for consistency's
sake: all the other arithmetic operators[*] promote their
operands with the same set of rules, so why should ~ be weird?

[*] The shift operators are an exception, justified by
the fact that they don't "combine" their operands in the
way + and % and so on do. See the Rationale, where there's
a recap of the debate over whether `1 << 2L' should be
evaluated in int (promoted type of left operand) or in
long (promoted type of shift count).

> 3. Which promotion rules apply when one of the
> operands is (long) long (unsigned) int ?

This is all spelled out in the Standard, and you've been
the description in N1124 that is unclear?

--

Eric Sosman, Aug 3, 2006
4. ### Eric SosmanGuest

Eric Sosman wrote On 08/03/06 12:42,:
>
> C's answer is the integer promotions (more generally,
> the "usual arithmetic promotions"), [...]

Sorry; "usual arithmetic conversions." A thinko
on my part.

--

Eric Sosman, Aug 3, 2006
5. ### CBFalconerGuest

wrote:
>

.... snip ...
>
> 2. Why do promotion rules apply when using the ~ operator ?

Because, in order to operate on a value, we usually need to pass it
through some sort of arithmetic processor. The default size for
that processor defines the size of an int. Thus the first option
is to convert the value into an int. longs, and/or long longs, may
require specialized processing, while floats and doubles are
usually aimed at a floating point processor.

--
Chuck F () ()
Available for consulting/temporary embedded and systems.

CBFalconer, Aug 4, 2006