How is it possible that the unary +/- operator causes an integral advance in "-a" or "+ a", "a" is an arithmetic data type constant / variable?
This seemingly trivial line comes from Book C by my Mike Banahan and Brady (section 188.8.131.52) .
I can figure out how implicit promotion comes into play in type expressions
depending on the types of the operands, but I can't figure out how and in what case the same could figure in something like
where b is any legal operand. Can you explain this and then give an example?
The extracted text follows:
Conventional arithmetic conversions apply to both operands of the binary form of the operator. Only integral promotions performed on operands of unary operator forms.
So that it doesn't go unnoticed, I am adding what I asked for based on OUAH's answer in the comment. The book says "
Only the integral promotions are performed
" ... This means that in an expression like
where "x" is a long double and "y" is a float, "y" will not rise to long double if we explicitly use the unary operator? I know what it would be, but ask for a clearer understanding of the "Integer promotions only ..." part nonetheless.
Can you explain how the promotion is going for the following bit operators? For the last three, I have to assume that whenever they are used in a variable is promoted to an integer type first? And what exactly does "normal arithmetic conversions" mean for the first three? Can you give me a small example? I don't want to post it as a separate question if it can be resolved here.
source to share
For a unary arithmetic operator, the C standard says (in section 184.108.40.206) that
Integer promotions are executed on the operand and the result is promoted.
It also defines the term in section 220.127.116.11:
If can represent all values of the original type (as is limited in width, for a bitfield), the value is converted to ; otherwise, it is converted to . They are called whole stocks. All other types are unchanged in whole promotions.
(References to draft N1570 standard C 2011.)
I believe the rationale for this is that an implementation is not required to support arithmetic on types narrower than
(one "word"). Operands narrower than
are converted to
before they work.
For binary operators (with two operands), there is an additional requirement that both operands are of the same type. Typical processors may have instructions to add two 32-bit signed integers, or two 32-bit unsigned integers, or two 64-bit signed or unsigned integers, but neither will add directly, like a 32-bit integer signed number and 64-bit unsigned integer. For this, we have the usual arithmetic conversions described in Section 18.104.22.168. These rules tell you, for example, what happens when you try to add
: the operand is
promoted by conversion to input
, and the addition adds two results
The shift operators do not require the usual arithmetic conversions, since both operands do not need to be of the same type. The left operand is the value to work on; the right-hand operand specifies the number of bits to offset.
Does this mean that in the type of expression
will not rise up
if we explicitly use a
The assignment causes the right operand to be converted to the type of the left operand. The expression
is evaluated regardless of the context in which it is displayed (this is true for most expressions). Thus, unary
is applied to its operand, which is of type
(integer stocks have no effect on this), which gives the result of type
. Assignment causes the value
to be converted
The title of your question asks how this can happen. I'm not sure what that means. The conversion rules are specified in the language standard. Compilers follow these rules.
source to share
I'm not sure, but I think each operation is promoted to the type it needs. First, the conversion is performed, and second, the operation is performed. The operation
modifies the value of the result variable, so promotion must be done and then the sign of the value is converted.
Operations like this
are also operations, so there is a Promotion + Operation process. I don't know if this code missed the code in this particular case.
source to share
During operations with binary operators, arithmetic progress is made to the highest required form, from int to long, float, or double.
But in unary operators
only promotions in Integer types 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
Thus, these integral spans do not work on other unary operators
source to share