【发布时间】:2021-01-28 01:09:14
【问题描述】:
假设一个整数表达式由多个无符号整数类型uint16_t 和uint32_t 组成。该表达式包含一个带括号的子表达式,其中所有元素的类型均为uint16_t。
在计算子表达式之前,是否应该将括号内的子表达式中的元素提升为uint32_t?
例如:
#include <stdint.h>
#include <stdio.h>
int main(void)
{
uint16_t a16 = 0x2000;
uint16_t b16 = 0x3000;
uint32_t c32 = 0x00000001;
uint32_t d32;
// Should (a16 * b16) be evaluated to 0x06000000, or to 0x0000?
// Should d32 be evaluated to 0x06000001, or to 0x00000001?
d32 = c32 + (a16 * b16);
printf("d32=0x%08x\n", d32);
return 0;
}
在 ideone 在线编译器中尝试此操作建议在乘法之前将 a16 和 b16 提升为 uint32_t。这是 C 标准规定的吗?为什么不在括号内计算为uint16_t?
【问题讨论】:
-
请注意括号是无关紧要的,因为正常的优先规则使它首先对乘法进行分组。
-
假设您的
d32 = b16 * (a16 + a16);略有不同,括号是不是很明显,它们是为了确保首先执行加法,而不是将总和限制为 16 位? -
@Barmar - 这个问题比这个特定的乘法示例更普遍。我可以把它变成一个溢出的添加,并用 c32 术语交换位置。
-
@WeatherVane - 不,实际上并不明显。可以认为计算是按顺序进行的,并且在每一步,编译器都会应用必要的提升规则。
-
我去年修复的最喜欢的错误实际上是
bonus = 1/2 * salary;,其中salary是double类型。这是了解隐式类型转换一步一步发生的试金石。
标签: c types integer-promotion type-promotion