I would like to know how to implicit casting works in case of expressions between unsigned int of various bits ie uint8_t,uint16_t etc and ways to avoid it explicitly. For this reason i sumarrized the following cases:
- How implicit casting in case of uint8_t addition,substraction,multiplication,division would work?
uint8_t A;
uint8_t B;
uint16_t C;
C= A+B; (uint8_t + uint8_t )
C= A-B; (uint8_t + uint8_t )
C= A*B; (uint8_t + uint8_t )
C= A/B; (uint8_t + uint8_t )
Explicit declaration would be C= static_cast<uint16_t>A+B; or C= static_cast<uint16_t>(A+B);.Is this correct? Is there any difference between C= static_cast<uint16_t>A+B; or C= static_cast<uint16_t>(A+B)?
- How implicit casting in case of expressions of unsigned int(with U literal)and uint8_t would work? Is there also a difference between the order that it matters ie 1UB;(unsined int * uint8_t ) or B1U;(uint8_t * uint8_t )
C= A+1U;(uint8_t + uint8_t )
C= A-1U;(uint8_t - uint8_t )
C= 1U*B;(uint8_t * uint8_t )
C= 1U/B;(uint8_t / uint8_t )
Explicit casting would be C= static_cast<uint16_t>A+1U; or C= static_cast<uint16_t>(A+1U); C= static_cast<uint16_t>1UB; or C= static_cast<uint16_t>(1UB);.Is that correct Is there any difference between those lines?
- How the implicit casting in case of expressions would work.Is the normal order take into account? What would it be the final type of the expression?
C= 1U/(A-1U); (unsigned int / (uint8_t -(unsigned int))
C= (C-(A/B))/B; (uint8_t -(uint8_t /(unsigned int))/(uint8_t)
How should static_cast look in this case? Only the first variable (1U or C) would define for the rest C= static_cast<uint8_t >(1U)/(A-1U);
- How the implicit casting in case of standard functions would work
sizeof(A) returns size_t
C=abs(-1*A) returns int in case of int parmaters
Explicit casting would be C= static_cast<uint16_t>sizeof(A) and C= static_cast<uint16_t>abs(-1*A). Is that correct? What about C= static_cast<uint16_t>abs(-1)*A)?
- How the implicit casting in case of function parameters would work.
uint16_t sum(uint16_t C1,uint16_t C2);
C=sum(A,B-1U/2U);
C=sum(A,1U/2U-B);
Explicit casting would be C= sum(static_cast<uint16_t>(A),static_cast<uint16_t>(B-1U/2U)). Is that correct?
I saw in Opencv a similar to static_cast function called saturate_cast. Would it be a beter solution in any of the above cases?
uint8_thas conversion rank lesser then typeintand typeintcan always hols the entire value range ofuint8_t,UINT8_MAXis 255 andinthas at least 16 bits.uint8_twill be promoted tointby integral promotion prior to operator. cppreference integral promotion fundamental types cstdintNo. These are not examples of declarations, type specifier is missing. They are using
operator=to assign a value to objectC. An "explicit declaration" would be a declaration that uses theautokeyword. cppreference declarationYes, on architecture where
intcan't hold all range of values ofuint16_t. In that particular case, the first expression first promotes the operands of+operator tounsigned int, while the second one carries the operation usinginttypes. The second expression is the same asC = A + B, becauseChas typeuint16_t. Except that particular case, on architectures whereintcan hold all range of values ofuint16_t, both operands will be promoted toint.C= static_cast<uint16_t>(A+B)is the same asC = A + B.First both operands undergo integral promotions.
unsigned intstays anduint8_tis promoted toint. Then the operands undergo integral conversions. Because one of the operands isunsignedand both operands have the same conversion rank, the signed operand is converted to unsigned type, ie.intis converted tounsigned int. arithmetic operators and arithmetic conversionsNo, the order of operands does not matter.
static_cast<uint16_t>1UBis a syntax error.C = static_cast<declatype(C)>(expr)is always equal toC = expr.I do not understand what is a "normal order". The operands and expression are evaluated according to their precedences.
The expression on the right side of
operator=is an rvalue ofunsigned inttype.The expression on the right side of
operator=is an rvalue ofunsigned inttype.Like anywhere else
static_cast<type>(expr)Each operator evaluates it's operands separately, one or two expressions at a time. The order of evaluations (and thus promotions) is ordered according to precedence of operators. order of evaluation and precedence and associativity
Like with any other type according to the rules of integer promotions.
size_tis just an implementation defined unsigned integer type.Both expression are syntax error. It's
static_cast<type> ( expression ). Braces are mandatory. For answer see above - doingC = static_cast<decltype(C)>(expr)is just equal toC = expr.What about it?
When arguments are not part of elipsis in a variadic function call then the arguments are converted to the argument type.
Yes, but what for? They will be converted to
uint16_tanyway."Better" is opinion based and vague. It depends on what you want to achieve. The
saturate_castis a simple template that specifically handles types with range grater then destination range. In such cases the argument is converted to the maximum/minimum of that type.For further research,. the draft of c++ standard is available online.