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 .

I can figure out how implicit promotion comes into play in type expressions c=a+b

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 -b

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 x=-y

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.

enter image description here


source to share

4 answers

For a unary arithmetic operator, the C standard says (in section that

Integer promotions are executed on the operand and the result is promoted.

It also defines the term in section

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. int


unsigned int

(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 int

(one "word"). Operands narrower than int

are converted to int

or to unsigned int

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 These rules tell you, for example, what happens when you try to add int

to double

: the operand is int

promoted by conversion to input double

, and the addition adds two results double


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 x=-y

, which x

is long double

and y

is float

, y

will not rise up long double

if we explicitly use a unary


The assignment causes the right operand to be converted to the type of the left operand. The expression -y

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 float

(integer stocks have no effect on this), which gives the result of type float

. Assignment causes the value float

to be converted long double

before assignment x


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.



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




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 -b

modifies the value of the result variable, so promotion must be done and then the sign of the value is converted.

Operations like this +b

are also operations, so there is a Promotion + Operation process. I don't know if this code missed the code in this particular case.



During operations with binary operators, arithmetic progress is made to the highest required form, from int to long, float, or double.

double c=2+3.5


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 ++a




All Articles