将uint8_t与一个数字进行比较

11

或许我没有正确理解C++,或者这是编译器的一个错误?

uint8_t a = 0x00;
uint8_t b = 0xFF;

if( a - b == 1 )
{
    doNothing();
}

doNothing 没有被调用(正如预期),因为 (a-b) 的结果被隐式转换为比较操作中第二个操作数的类型。对于数字,它是带符号整数。好的。

if( a - b == (uint8_t)1 )
{
    doNothing();
}

doNothing仍然没有被调用,但我现在不理解原因!我已经将数字显式转换为uint8了!

if( (uint8_t)(a - b) == 1 )
{
    doNothing();
}

现在doNothing终于被调用了,但为什么呢?为什么两个uint8的相减会返回一个int呢?

编译器是ARM Cortex M3的uVision ARMCC。


请参阅此问题,以获得关于转换规则的更全面解释:https://dev59.com/n2035IYBdhLWcg3wMNGW - Dale Wilson
3
据我记得,Keil C 并不完全符合标准,因此人们在使用时可能会感到相当困惑。不过,在这种情况下,它似乎遵循了标准。顺便问一下,为什么这个问题被同时标记为 C 和 C++?你正在使用哪种语言? - Keith Thompson
不是问题,但是没有隐式转换这种东西。强制类型转换是你在源代码中编写的内容,告诉编译器进行转换。由强制类型转换引起的转换是显式转换。编译器在没有强制类型转换的情况下进行的转换是隐式转换。 - Pete Becker
@Amomum,顺便说一下,即使代码片段#3可以工作,它也是未定义的行为,你不应该依赖它。 - ZijingWu
1
@Amomum,抱歉我的错,我刚刚查了标准,它已经定义并且转换的结果是1。 - ZijingWu
显示剩余5条评论
3个回答

12
在表达式 a - b 中,进行减法之前,操作数被提升为 int 类型,因此结果是 -255,而不是 1。
这就是为什么第一个和第二个例子都失败了;这与 == 的另一个操作数无关。第三个例子将 -255 转换回 uint8_t 类型,使其对 256 取模,所以结果是预期的 1。

在第三种情况下,(uint8_t)(a - b) 的结果为 (uint8_t) 1。这个 1 是否会被提升为 int 来执行 bool operator == (int, int) - chux - Reinstate Monica
1
@chux:是的,它确实会这样做。所有内置运算符的操作数都会被提升至至少int类型,或者更大的类型(如果需要的话)。 - Mike Seymour

2

虽然我在数学和十六进制方面不是最好的,但看起来 a = 0 并且 b = 255,所以该等式结果为 -255 而非 1。


1
ARM Cortex M3是一种32位处理器。所以a-b的结果是0xFFFFFF01,而不是1(在32位表示中,1 ==> 0x00000001),因此doNothing()函数没有被调用!
在情况2中,如果您将1强制转换为uint8_t,则0xFFFFFF01不等于0x01,因此再次未调用doNothing()函数!
在情况3中,当您将a-b输出强制转换为uint8_t时,a-b的结果为0x01,等于1,因此调用doNothing。

为什么两个uint8_t相减的结果默认不是uint8_t? - Amomum
由于32位处理器的限制,所有变量的长度都将为32位!通过使用uint8_t类型的变量,您将仅使用该变量的低8位,其余24位将为0。为了更容易理解,uint8_t类型转换相当于使用(0x000000FF)掩码对32位变量进行掩码。在32位处理中,所有变量或常量的长度都是32位!uint8_t只告诉您将在这32位中使用多少位!在您的情况下,a-b ==> 0x00000000 - 0x000000FF将导致0xFFFFFF01。因此,如果您将其类型转换为uint8_t,则结果将为0x00000001。 - Basavaraju B V
1
@Amomum 因为标准规定如此。在进行任何二元操作之前,比 int 更小的类型会被提升为 int(如果它们适合的话;否则为 unsigned)。 - James Kanze
我就是不明白,为什么这个操作的结果没有自动转换回uint8_t,为什么高位没有被屏蔽掉。对我来说,这似乎很奇怪。 - Amomum
@JamesKanze,嗯,这基本上就解释了。即使我明确地进行了强制转换(uint8_t)1 - 它仍然被转换为int? - Amomum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接