【发布时间】:2009-04-26 21:27:05
【问题描述】:
我有以下 C 代码:
#define PRR_SCALE 255
...
uint8_t a = 3;
uint8_t b = 4;
uint8_t prr;
prr = (PRR_SCALE * a) / b;
printf("prr: %u\n", prr);
如果我编译它(使用 msp430 平台编译器,对于名为 contiki 的小型嵌入式操作系统),结果为 0,而我预期为 191。 (uint8_t 被定义为无符号字符)
如果我将其更改为:
uint8_t a = 3;
uint8_t b = 4;
uint8_t c = 255;
uint8_t prr;
prr = (c * a) / b;
printf("prr: %u\n", prr);
它运行正常并打印 191。
在 Ubuntu 机器上使用 gcc 编译这个“通常”的简单版本会在两种情况下打印正确的值。
我不确定这是为什么。我可以通过预先将 DEFINEd 值分配给变量来规避它,但我宁愿不这样做。
有人知道这是为什么吗?也许带有指向更多相关信息的链接?
【问题讨论】:
-
我当然希望两者都打印 191。在第二种情况下,第一个 c 和 a 被独立提升为 int,因此它们的乘法不会溢出。在第一种情况下也会发生同样的情况(尽管 PRR_SCALE 已经是 int - 但这也不会改变 a 到 int 的提升)。你盒子上的 gcc 表现得很好。
-
检查是否包含标头 stdio.h。我知道 msp430 的一个编译器确实允许发生隐式函数声明:如果是这种情况,对 printf 的调用将导致未定义的行为,因此将解释“0”结果。只是我的两分钱。不要认为这值得回答:)
-
只是出于好奇:如果将 PRR_SCALE 设置为 255U 会发生什么?
-
@Jochen:打印结果是255!?我不知道为什么(再次)......
-
msp430 的 mul 代码使用乘法仿真代码(无硬件支持)iirc。所以很可能存在一些我怀疑的错误(尽管这是一个相当 C 前端的问题)。作为修复,尝试 (+PRR_SCALE * +a) / +b;并添加一条评论,“+”将手动提升它们。也许这会有所帮助?
标签: c embedded overflow multiplication msp430