C++ C++;11是否进行与运算符优先级相关的算术类型转换?

C++ C++;11是否进行与运算符优先级相关的算术类型转换?,c++,c++11,floating-point,type-conversion,integer-overflow,C++,C++11,Floating Point,Type Conversion,Integer Overflow,如果我有以下代码: double compute(double val1, int32_t val2, int32_t val3, int32_t val4) { return val1 + val2 * val3 * val4; } C++11语言如何指定执行乘法?例如,val1、val2和val3是否根据运算符优先级乘以32位整数,可能会溢出,然后转换为双精度,或者是否作为双精度 总的来说,标准在

如果我有以下代码:

double compute(double val1,
               int32_t val2,
               int32_t val3,
               int32_t val4) {
  return val1 + val2 * val3 * val4;
}
C++11语言如何指定执行乘法?例如,
val1
val2
val3
是否根据运算符优先级乘以32位整数,可能会溢出,然后转换为双精度,或者是否作为双精度

总的来说,标准在这个问题上到底说了些什么?在C++的后续版本中(例如C++ 17)是否发生了变化?

< p>表达式

val1 + val2 * val3 * val4
具有类型为
double
,但乘法部分的类型为
int32\u t
。如果我们应用关于如何评估的规则,我们已经

val1 + (val2 * val3 * val4)
由于乘法具有更高的优先级,因此计算乘法时将不考虑
val1
的类型,并且由于所有操作数都具有相同的类型,因此结果类型将与操作数相同。然后将该结果转换为
double
,并添加到
val1
。这种行为在C++的任何版本中都没有改变。 要使乘法成为
double
,需要将
val2
val3
转换为double,这将使整个乘法部分作为
double
进行计算。那看起来像

val1 + (static_cast<double>(val2) * val3 * val4)
val1+(静态施法(val2)*val3*val4)

括号是不需要的,但我喜欢用它们来表示分组

运算符优先级意味着乘法发生在加法之前。表达式
val2*val3*val4
被计算为
int32_t
——也具有任何溢出效应。然后将其结果转换为
double
,然后再添加到
val1
。C++ 11之前C++的所有版本都是相同的。固定宽度类型,如
int32_t
,在C++11.fwiw之前不是标准的,因为您首先使用的是double值,所以当它们影响double值时,所有期望的结果都将变成double,并且会发生转换。从左到右
val1+((val2*val3)*val4)
完成同样事情的更简洁的方法是
val1+(1.0*val2*val3*val4)
@dan04简洁但不明确。下一个读取代码的人可能太聪明了,删除
1.0*
,因为这似乎不会影响结果,而删除
静态\u cast的人只会得到他们应得的;)