Why is static_cast on an expression acting distributively?

荒凉一梦 提交于 2019-12-05 05:47:32

For most of the arithmetic operators (including -), the operands undergo the usual arithmetic conversions. One of these conversions is that any value of type narrower than int is promoted to int. (Standard reference: [expr]/10).

So the expression foo - bar becomes (int)foo - (int)bar giving (int)-245. Then you cast that to uint32_t which will give a large positive number.

To get the result you are intending , cast to uint8_t instead of uint32_t. Alternatively, use the modulus operator % on the result of the cast to uint32_t.

It is not possible to do a calculation directly in narrower precision than int

Shafik Yaghmour

The issue is not the static_cast but the subtraction, the operands of additive operators have the usual arithmetic conversions applied to them and in this case the integral promotions which results in both operands of the subtraction being promoted to int:

static_cast<uint32_t>(foo - bar);
                      ^^^   ^^^

On the other hand:

static_cast<uint8_t>(foo - bar);

would produce desired result.

from the draft C++ standard section 5.7 [expr.add] says:

The additive operators + and - group left-to-right. The usual arithmetic conversions are performed for operands of arithmetic or enumeration type.

this results in the integral promotions, section 5 [expr] says:

Otherwise, the integral promotions (4.5) shall be performed on both operands

which results in both operands being converted to int, section 4.5 [conv.prom] says:

A prvalue of an integer type other than bool, char16_t, char32_t, or wchar_t whose integer conversion rank (4.13) is less than the rank of int can be converted to a prvalue of type int if int can represent all the values of the source type; otherwise, the source prvalue can be converted to a prvalue of type unsigned int.

and then the static_cast to uint32_t is applied which results in a conversion which is defined as follows in section 4.7 [conv.integral]:

If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2n where n is the number of bits used to represent the unsigned type). [

The questions Why must a short be converted to an int before arithmetic operations in C and C++? explains why types smaller than int are promoted for arithmetic operations.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!