How to determine the type of result of an arithmetic expression?
- oneweird question. Usually the most common of all parts of an expression. - pavel
- oneLook in the language specification for the rules by which this type is determined. - AnT
3 answers
Operands of arithmetic types in sub-expressions must be converted to a general type so that you can perform an operation and get the type of the resulting expression.
The process of obtaining a general type for the operands of operations and the derivation of the resulting type is called usual arithmetic conversions .
The order of the type conversion of the operands of arithmetic types in expressions is defined as follows, as described in Section 5 Expressions of the C ++ Standard:
- (10.2) If you have been converted to long double.
That is, if one of the operands is of type long double , then the second operand is cast to that type.
- (10.3) Otherwise, if any, can be converted to double.
Otherwise, if one of the operands is of type double , then the second operand must also be cast to this type.
- (10.4) Otherwise, if any, it’s converted to float.
Otherwise, if one operand is of type float , then the second operand must also be cast to this type.
- (10.5) Otherwise, it’s not necessary, but it’s not
Otherwise, integer casting is used.
- (10.5.1) If both operands are not the same type, no further conversion is needed.
If after this the types coincide, then no further conversions are performed.
- (10.5.2) Otherwise, if they are unsigned integer types or not, then.
Otherwise, if both operands are unsigned or signed, then an operand with a lower rank is converted to an operand type with a higher rank.
- (10.5.3) Otherwise, if you can’t have it? integer type.
Otherwise, if the operand of an unsigned integer type has a rank greater than or equal to the rank of the signed integer type of the second operand, then the second operand is converted to the unsigned integer type of the first operand.
- (10.5.4) If you type, you will be able to with signed integer type.
Otherwise, if the operand of signed integer type can represent all values of the unsigned integer type of the second operand, then the second operand is converted to the type of the first operand.
- (10.5.5) Otherwise, it can be used with the signed integer type.
Otherwise, both operands must be converted to an unsigned integer type corresponding to the signed integer type of the first operand.
Here is a simple example.
There are two ads.
long int x = 0; unsigned int y = 0; and both types, long int and unsigned int , occupy 4 bytes .
The question is, what type will have varazheniya
x + y I assure you that many programmers who have not read this section of the standard will not be able to answer this question :)
Answer: according to the last subclause of the quotation, the type of expression is unsigned long int .
Keep in mind that the rank of the type long int always greater than the rank of int and, accordingly, the rank of unsigned int .
- Plus. What is the edition of the Standard? - Majestio
- one@Majestio I now have at hand Document Number: N4296 Date: 2014-11-19. - Vlad from Moscow
- Strictly speaking, paragraph 10.5.3 will work first and the answer is
unsigned int(in practice, of course, for 4-bytelongandintno difference in code generation, so this is an empty textbook in the spirit of standards ...) - avp - @avp What is item 10.5.3? - Vlad from Moscow
- @av And the unsigned int answer is incorrect. As I wrote, the correct answer is unsigned long int. Naturally, provided that the two types are the same size. - Vlad from Moscow
Like std::common_type<Arg1, Arg2, ...>::type :)
- @AnT Thank you, corrected. - Harry
Why don't you use auto , and then when you need a result type — decltype(...) ?
Example (very banal):
auto res = 14.88 + 12; std::vector<decltype(res)> vec;