Reputation: 1652
This seemingly trivial line is taken from the C book my Mike Banahan & Brady (Section 2.8.8.2).
I can understand how implicit promotion comes into play in expressions like c=a+b
depending on the types of the operands, but I am unable to grasp how and in which case the same can figure in something like -b
, where b is any legitimate operand. Can you explain it and then give a proper example?
Extracted text follows:
The usual arithmetic conversions are applied to both of the operands of the binary forms of the operators. Only the integral promotions are performed on the operands of the unary forms of the operators.
Update:
Lest it goes unnoticed, here I am adding what I asked based on OUAH's answer in a comment–
The book says 'Only the integral promotions are performed
'...Does it mean that in an expression like x=-y
, where 'x' is a long double and 'y' is a float, 'y' won't be promoted to long double if we explicitly use a unary operator? I know it would be, but asking it nevertheless to get a clearer idea about the "Only the integeral promotions..." part.
Update:
Can you explain with example how promotion comes into play for the following bit-wise operators? For the last three, should I assume that whenever those are used on a variable, it is promoted to integer type first? And what exactly does the "usual arithmetic conversions" mean for the first three? Can you give a small example? I don't want to post it as a separate question if it can be settled here.
Upvotes: 0
Views: 877
Reputation: 263637
For a unary arithmetic operator, the C standard says (in section 6.5.3.3) that
The integer promotions are performed on the operand, and the result has the promoted type.
It also defines the term, in section 6.3.1.1:
If an
int
can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to anint
; otherwise, it is converted to anunsigned int
. These are called the integer promotions. All other types are unchanged by the integer promotions.
(References are to the N1570 draft of the 2011 C standard.)
I believe the rationale for this is that implementations are not required to support any arithmetic operations on types narrower than int
(one "word"). Operands narrower than an int
are converted to int
, or to unsigned int
, before they're operated on.
For binary operators (those taking two operands), there's an additional requirement, that both operands must be of the same type. Typical CPUs might have instructions to add two 32-bit signed integers, or two 32-bit unsigned integers, or two 64-bit signed or unsigned integers, but none that will directly add, for example, a 32-bit signed integer and a 64-bit unsigned integer. To allow for this, we have the usual arithmetic conversions, described in section 6.3.1.8. These rules tell you, for example, what happens when you try to add an int
to a double
: the int
operand is promoted, by conversion, to type double
, and the addition adds the resulting two double
operands.
The shift operators don't require the usual arithmetic conversions, since there's no particular need for both operands to be of the same type. The left operand is a value to be operated on; the right operand specifies the number of bits to shift it.
Does it mean that in an expression like
x=-y
, wherex
is along double
andy
is afloat
,y
won't be promoted tolong double
if we explicitly use aunary
operator?
Assignment causes the right operand to be converted to the type of the left operand. The expression -y
is evaluated independently of the context in which it appears (this is true for most expressions). So the unary -
is applied to its operand, which is of type float
(the integer promotions don't affect that), yielding a result of type float
. The assignment causes that float
value to be converted to long double
before being assigned to x
.
The title of your question asks how this can possibly happen. I'm not sure what that means. The conversion rules are specified in the language standard. Compilers follow those rules.
Upvotes: 2
Reputation: 688
During operations with binary operators arithmetic promotion to highest needed form is done, from int to long, float, or double.
double c=2+3.5
But in unary operators +
,-
only promotions in Integer type datatypes are allowed. From short to int or long.
unsigned char a=255;
cout<<sizeof(a)<<endl; //prints 1
cout<<sizeof(+a)<<endl; //prints 4
cout<<sizeof(++a)<<endl; //prints 1
So this Integral promtions does not work on other unary operators ++a
and a++
Upvotes: 0
Reputation: 25
I'm not sure, but I think that every operation is promoted to a proper type. First the conversion is done, and secondly the operation is done. The -b
operation changes the value of the result variable, so the promotion should be done and then the value sign is converted.
Operations like +b
is also an operations, so there are an Promotion + Operation process. I don't know if a code optimization coud skip this process in this concrete case.
Upvotes: 0
Reputation: 145919
Take this example on a 32-bit system:
unsigned char a = 42;
printf("%zu\n", sizeof a); // prints 1
printf("%zu\n", sizeof +a); // prints 4, a has been promoted to int
Upvotes: 4