简体   繁体   English

为什么这种情况总是如此? (pktNum!= invPktNum)

[英]Why is this condition always true? (pktNum != invPktNum)

When I compile the following code, my compiler complains that the following line is always true. 当我编译以下代码时,我的编译器抱怨以下行始终为true。 I think I may have a faulty understanding of the != operator... 我想我可能对!=运算符有错误的理解......

if (pktNum != ~invPktNum) {
    return 1;
}

I'm trying to verify that invPktNum is indeed the inverse of pktNum. 我试图验证invPktNum确实是pktNum的反转。 If not, exit immediately, otherwise proceed as normal. 如果没有,请立即退出,否则继续正常进行。

I've checked and pktNum an unsigned char that is 0x01 and invPktNum is an unsigned char that is 0xFE at the time of comparison. 我已经检查并且pktNum是一个0x01的无符号字符,而invPktNum是一个在比较时为0xFE的无符号字符。

Can anybody enlighten me? 任何人都可以开导我吗? Thanks in advance! 提前致谢!

In C, values in most expressions that are of a type narrower than int are promoted to a wider type before the calculation takes place. 在C中,大多数表达式中比int更窄的值的值在计算发生之前被提升为更宽的类型。 If int is wide enough to hold all the values of the narrower type, then it is promoted to int ; 如果int足够宽以容纳较窄类型的所有值,则将其提升为int ; otherwise it is promoted to unsigned int . 否则它被提升为unsigned int

In this case, int is wide enough to hold all the values of your unsigned char , so your values are promoted to int . 在这种情况下, int足够宽以容纳unsigned char所有值,因此您的值将提升为int

pktNum (and thus, the promoted pktNum ) can have a value between 0 and 255 inclusive. pktNum (因此,提升的pktNum )可以具有0到255之间的值(包括0和255)。 This is the value that will be used on the left hand side of the != operator. 这是将在!=运算符的左侧使用的值。

invPktNum can likewise have a value between 0 and 255 inclusive. invPktNum同样可以具有0到255之间的值。 This value will be promoted to int , and then bitwise-negated. 此值将提升为int ,然后按位取反。 The result of this bitwise negation will always be a negative number, since the sign bit will be negated. 这种按位否定的结果将始终为负数 ,因为符号位将被否定。 This is the value that will be used on the right hand side of the != operator. 这是将在!=运算符右侧使用的值。

No negative number can ever be equal to the promoted pktNum , so the condition is always true. 没有负数可以等于提升的pktNum ,因此条件始终为真。

To perform the calculation that you actually want to, you need to mask out the lower eight bits after the negation: 要执行您真正想要的计算,您需要在否定后屏蔽低8位:

if (pktNum != (~invPktNum & 0xff)) {
    return 1;
}

Or alternatively, you can just negate the bits you're interested in: 或者,您可以忽略您感兴趣的位:

if (pktNum != (invPktNum ^ 0xff)) {
    return 1;
}

You're looking at 8-bit values. 你正在看8位值。 I bet that pktNum and invPktNum are 32-bit values, so you're comparing 0x000000fe to 0xfffffffe. 我敢打赌,pktNum和invPktNum是32位值,所以你要比较0x000000fe和0xfffffffe。

Perhaps the simple type independent test is: 也许简单的类型独立测试是:

if (0 == (pktNum & pkNum)) {

Which is equal to: 这相当于:

if (0 == (0xfe & 0x01)) {

Quickly tested with http://codepad.org/nziOGYJG seems to work with multiple signed and unsigned long / int types. 使用http://codepad.org/nziOGYJG快速测试似乎可以使用多个signed和unsigned long / int类型。

Out of interest anybody have any comments? 出于兴趣任何人都有任何意见?

Assuming the following: 假设如下:

invPktNum = ~pktNum

then your comparison is equivalent to: 然后你的比较相当于:

if (pktNum != ~(~pktNum)) {

or 要么

if (pktNum != pktNum) {

which is always false. 这总是假的。 Unless invPktNum has a different definition in your code which is not shown. 除非invPktNum在您的代码中有不同的定义,否则不会显示。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM