Integer Promotions

F

Fred

I'm having terrible trouble trying to work out exactly which of the
promotions one reads about in old books are still present in current C -
and there seems to be a distinction between promotion for function
arguments versus expressions?

For example, consider the following code:

short u; /* declare u as a short */
(void) (u=10); /* set u to 10 */

Am I right in thinking the following happens:
1. 10 is promoted to an int.
2. This expression is evaluated as an int to yield 10.
3. Then the result is demoted to a short (equal to 10) and stored in u.
(4. And as usual we discard the value of the assigment expression)

Is this also why there are suffixes for long and unsigned integer
constants, but no suffixes for shorts and chars? Because these
automatically become ints as soon as they appear?

It does seem unnecessarily indirect to do this promotion and demotion
all the time - half of one's compiled code must end up just moving back
and forth between different integer types!
 
P

pete

Fred said:
I'm having terrible trouble trying to work out exactly which of the
promotions one reads about in old books are still present in current C -
and there seems to be a distinction between promotion for function
arguments versus expressions?

For example, consider the following code:

short u; /* declare u as a short */
(void) (u=10); /* set u to 10 */

Am I right in thinking the following happens:
1. 10 is promoted to an int.
2. This expression is evaluated as an int to yield 10.

No. (10) starts out as an int.
sizeof(10) equals sizeof(int) always everywhere.
3. Then the result is demoted to a short (equal to 10)
and stored in u.
(4. And as usual we discard the value of the assigment expression)

Points 3 and 4 seem OK
 
R

Richard Heathfield

Fred said:

For example, consider the following code:

short u; /* declare u as a short */
(void) (u=10); /* set u to 10 */

Am I right in thinking the following happens:
1. 10 is promoted to an int.
2. This expression is evaluated as an int to yield 10.
3. Then the result is demoted to a short (equal to 10) and stored in u.

Pete has already dealt with these.
(4. And as usual we discard the value of the assigment expression)

That isn't actually "as usual". Hardly anyone does that, as it's utterly
pointless.
 
J

jacob navia

Fred said:
I'm having terrible trouble trying to work out exactly which of the
promotions one reads about in old books are still present in current C -
and there seems to be a distinction between promotion for function
arguments versus expressions?

For example, consider the following code:

short u; /* declare u as a short */
(void) (u=10); /* set u to 10 */

Am I right in thinking the following happens:
1. 10 is promoted to an int.
2. This expression is evaluated as an int to yield 10.
3. Then the result is demoted to a short (equal to 10) and stored in u.
(4. And as usual we discard the value of the assigment expression)

Is this also why there are suffixes for long and unsigned integer
constants, but no suffixes for shorts and chars? Because these
automatically become ints as soon as they appear?

It does seem unnecessarily indirect to do this promotion and demotion
all the time - half of one's compiled code must end up just moving back
and forth between different integer types!

As stated before 1) and 2) are one operation. The constant starts
as an integer, since it is not suffixed and it is not floating
point.

3) In some architectures, you can assign directly a constant to a memory
location, without storing them in a register first. This means that 3)
can be optimized to just

Assign to the address of u, the 16 bit constant 10.

In other architectures, a constant can only be loaded into a register
and then stored. This would be two instructions instead of one.
 
P

Philip Potter

Richard said:
Fred said:



Pete has already dealt with these.


That isn't actually "as usual". Hardly anyone does that, as it's utterly
pointless.

No, I disagree. It's quite sensible to discard the value of the assignment
expression, because the assignment itself was the purpose of the statement.

Casting the assignment to void, however, is pointless. Luckily, it isn't
necessary to do this in order to discard the value.
 
P

Philip Potter

Fred said:
I'm having terrible trouble trying to work out exactly which of the
promotions one reads about in old books are still present in current C -
and there seems to be a distinction between promotion for function
arguments versus expressions?

For example, consider the following code:

short u; /* declare u as a short */
(void) (u=10); /* set u to 10 */

Am I right in thinking the following happens:
1. 10 is promoted to an int.
2. This expression is evaluated as an int to yield 10.
3. Then the result is demoted to a short (equal to 10) and stored in u.
(4. And as usual we discard the value of the assigment expression)
>
Is this also why there are suffixes for long and unsigned integer
constants, but no suffixes for shorts and chars? Because these
automatically become ints as soon as they appear?

It does seem unnecessarily indirect to do this promotion and demotion
all the time - half of one's compiled code must end up just moving back
and forth between different integer types!

It depends what you mean by "happens". This is the way what is happening is
described by the standard, and the correct way to think about it.

However, the compiler is allowed to compile this to any code which behaves "as
if" the above steps had been followed, that is, any code which has identical and
indistinguishable results.

In the above program, the compiler can directly set u to the short constant 10,
without involving an intermediate int constant. It can do this because there is
no way the program could tell the difference. However, the version of events
above, with the intermediate int constant, is the gold standard by which any
program will be measured for conformity. (Conformingness?)

So no, there is no need to worry about all these promotions and demotions
wasting your time.
 
R

Richard Heathfield

Philip Potter said:
No, I disagree. It's quite sensible to discard the value of the
assignment expression, because the assignment itself was the purpose of
the statement.

Casting the assignment to void, however, is pointless. Luckily, it isn't
necessary to do this in order to discard the value.

Ach! Out-pedanted again! (And you are, of course, perfectly correct.)
 
B

Ben Bacarisse

As stated before 1) and 2) are one operation. The constant starts
as an integer, since it is not suffixed and it is not floating
point.

It would be an integer even with a suffix. You mean int. Also one
needs to add that, for it to be an int, it must fit in an int.
Hexadecimal and octal constants might also be unsigned, so one needs
to consider the prefix also.
 
F

Fred

Fred said:



Pete has already dealt with these.


That isn't actually "as usual". Hardly anyone does that, as it's utterly
pointless.

Well, I try to make my code keep lint quiet even with strict settings...
cures a lot of bugs.
 
J

Jack Klein

Well, I try to make my code keep lint quiet even with strict settings...
cures a lot of bugs.

If you have a version of lint that complains about discarding the
value resulting from a simple assignment, either it provides, and you
are using, an insanely paranoid option, or the particular lint utility
(or its author(s)) are pathologically unfamiliar with C.

My quick mental review of C code written and read over the past
quarter century comes up with the unscientific conclusion that the
value of an assignment statement is ignored more than 90% of the time.

In fact, if one uses MISRA rules with PC Lint, one gets a MISRA
violation for:

int x, y;
x = y = 3;

....unless you parenthesize as:

x = (y = 3);

....as depending on operator precedence.

Personally I think that warning is worded incorrectly, and superfluous
when the objects are of the same type, but with different wording
would be valid for:

double d1, d2 = sqrt(2.0);
int x;
d1 = x = d2;

....because there is a distinct possibility of unintentional data loss
in this statement. d1 will receive the value of 1.0, and not 1.414...

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,992
Messages
2,570,220
Members
46,805
Latest member
ClydeHeld1

Latest Threads

Top