Type promotion rules?

B

BigMan

Can someone cite the rules for type promotion in C++?

And, in particular, what is the type of the result of adding 2 values
of type char?
 
B

Bob Hairgrove

Can someone cite the rules for type promotion in C++?

Look for section 4.5 of the standard.
And, in particular, what is the type of the result of adding 2 values
of type char?

The result of an addition is an rvalue which is implicitly promoted to
type int if necessary, and if an int can contain the resulting value.
This is true on any platform where sizeof(int) > sizeof(char).

But beware of the fact that char might be treated as signed char by
your compiler, though (see my previous reply in a different thread).
 
M

Me

And, in particular, what is the type of the result of adding 2 values
The result of an addition is an rvalue which is implicitly promoted to
type int if necessary, and if an int can contain the resulting value.
This is true on any platform where sizeof(int) > sizeof(char).

Technically on a platform with sizeof(int) > 1, it can still have a
smaller range than char if the underlying type of char is unsigned char
and the reason int is larger is because of padding bits. But this would
be a very stupid (but allowed) implementation.
 
B

BigMan

Firstly, according to item 4.5.1 the result of adding 2 chars might be
unsigned int (e.g. when an int cannot represent all the values of a
char). Is this correct?

Secondly, where is it stated that an int can represent all the values
of a signed char if sizeof(int) > sizeof(signed char)?
 
B

BigMan

What promotions should be performed when compiling this piece of code
if an int can represent all the values of an unsigned short:

unsigned short a = 0;
unsigned int b = 0;
signed int c = 0;
bool d = a < b; // Should a be promoted to int or to unsigned int
according to 4.5.1? Some compilers seem to promote it to unsigned int.
bool e = a < c; // A seems to get promoted to int, which is fine.
 
B

Bob Hairgrove

What promotions should be performed when compiling this piece of code
if an int can represent all the values of an unsigned short:

unsigned short a = 0;
unsigned int b = 0;
signed int c = 0;
bool d = a < b; // Should a be promoted to int or to unsigned int
according to 4.5.1? Some compilers seem to promote it to unsigned int.

Neither; bool is an integral type, and "a < b" is a Boolean expression
producing a Boolean result. Both a and b are unsigned integral
expressions. Since the return value is assigned to another Boolean
variable, no conversion or promotion is necessary.

It is possible that some compilers will promote the result of "a<b" to
an rvalue of type unsigned int, then convert that to a Boolean type.
As long as the types involved are all either Boolean or unsigned
integral types, I believe the behavior is well defined by the standard
since Boolean values can only be either 0 or 1 (the Standard says so
somewhere around 4.5 or thereabouts, I'm not sure where, but I saw
it).
bool e = a < c; // A seems to get promoted to int, which is fine.

This is a "horse of an entirely different color". c is signed, a
isn't. Depending on a's value, getting "promoted" to int may cause
problems. It is also possible that c could be promoted to unsigned int
if a were negative when cast to signed. Most compilers would issue a
diagnostic here about "comparing signed with unsigned value" anyway.
 
O

Old Wolf

Bob said:
Neither; bool is an integral type, and "a < b" is a Boolean
expression producing a Boolean result. Both a and b are unsigned
integral expressions.
Since the return value is assigned to another Boolean variable,
no conversion or promotion is necessary.

Actually, 'a' is an unsigned short. In this case it will
be promoted to unsigned int, because 'b' is an unsigned int.
It is possible that some compilers will promote the result
of "a<b" to an rvalue of type unsigned int, then convert
that to a Boolean type.

If anything, it would be a signed int (promotions only promote
to unsigned int, if the original type doesn't "fit in" a signed
int -- but Bool does).
However I can't think of any way that conforming code could detect
this promotion.
As long as the types involved are all either Boolean or unsigned
integral types, I believe the behavior is well defined by the standard
since Boolean values can only be either 0 or 1 (the Standard says so
somewhere around 4.5 or thereabouts, I'm not sure where, but I saw
it).

Boolean values can only be true or false. When true is converted
to another integral type, the converted value is 1, etc.
This is a "horse of an entirely different color". c is signed, a
isn't. Depending on a's value, getting "promoted" to int may cause
problems. It is also possible that c could be promoted to unsigned
int if a were negative when cast to signed.

The promotion occurs at compile-time, ie. it doesn't depend
on the value of 'a'. It depends on the possible range of values
of 'a'. If EVERY possible value of 'a' can be represented by a
signed int, the promotion will be to signed int. Otherwise, both
operands will promote to unsigned int.
Most compilers would issue a diagnostic here about "comparing signed
with unsigned value" anyway.

In my experience, most compilers wouldn't warn for this one,
but would warn for the first example. They apply the default
promotion of 'unsigned short' --> 'signed int' before deciding
whether to issue this warning. Of course, since this diagnostic
is not required, compilers can do what they like.
 
B

BigMan

The promotion occurs at compile-time, ie. it doesn't depend
on the value of 'a'. It depends on the possible range of values
of 'a'. If EVERY possible value of 'a' can be represented by a
signed int, the promotion will be to signed int. Otherwise, both
operands will promote to unsigned int.

According to item 4.5/1 in the standard integral promotions to signed
int are done without loss of information:

"An rvalue of type char, signed char, unsigned char, short int, or
unsigned short
int can be converted to an rvalue of type int if int can represent all
the values of the source type; otherwise, the source rvalue can be
converted to an rvalue of type unsigned int."

When a signed int cannot represent all the values of the source type,
the promotion is to unsigned int. Does this imply that if a signed int
cannot represent all the values of the source type, then an unsigned
int can?
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top