C++ 比较整数提升后的结果
以下情况:C++ 比较整数提升后的结果,c++,c,integer,bit-manipulation,integer-promotion,C++,C,Integer,Bit Manipulation,Integer Promotion,以下情况: #include <stdbool.h> #include <stdint.h> #define CHECKVAR(var__, compl__) ((var__^compl__)==-1); int main() { uint8_t var; uint8_t complementvar; var=3; complementvar=~var; bool checkOK=CHECKVAR(var,complementvar); /*-> I expe
#include <stdbool.h>
#include <stdint.h>
#define CHECKVAR(var__, compl__) ((var__^compl__)==-1);
int main()
{
uint8_t var;
uint8_t complementvar;
var=3;
complementvar=~var;
bool checkOK=CHECKVAR(var,complementvar); /*-> I expect that all bits are set and hereby it is equal to "-1", but instead i get "false" */
return 0;
}
我有宏,用于在结构中存储变量的补码及其原始值。对于另一个宏,我想检查原始值是否等于存储的补码值的补码。但奇怪的是,我没有得到预期的结果。
为了简化操作,这会导致以下情况:
#include <stdbool.h>
#include <stdint.h>
#define CHECKVAR(var__, compl__) ((var__^compl__)==-1);
int main()
{
uint8_t var;
uint8_t complementvar;
var=3;
complementvar=~var;
bool checkOK=CHECKVAR(var,complementvar); /*-> I expect that all bits are set and hereby it is equal to "-1", but instead i get "false" */
return 0;
}
#包括
#包括
#定义CHECKVAR(var,compl)(var,compl)=-1);
int main()
{
uint8_t var;
uint8_t;
var=3;
互补var=~var;
bool checkOK=CHECKVAR(var,complementvar);/*->我希望所有位都被设置,因此它等于“-1”,但我得到的是“false”*/
返回0;
}
我的期望是(例如,在32位系统上:
complementvar
具有值0xfffffc
(在~operator对int进行整数提升后,通过隐式将其向下转换为uint8
,将左值赋给complementvar
)- 2a)<代码>变量:0000 0011;
complementvar:1111111111111111111111111111100
- 2b)\n现在,对var和互补var进行异或运算将导致
1111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111==1111111111111111111111111111111111111111
的结果应该是true,但我总是收到false,因为异或运算的结果(对我来说很奇怪)是0x000000ff0xfffffffc
不,看看这个代码:
uint8_t complementvar;
complementvar=~var;
~var
将计算为您期望的值,但是complementvar
具有类型uint8\t
,因此转换只会导致0xfc
在您的检查步骤中,这将再次升级为int
,但由于uint8\u t
是一种无符号的类型,此处不进行符号扩展,只需添加0
位即可。这解释了通过xoring(^
)得到的结果
补码运算后,complementvar的值为0xfffffffc
不,看看这个代码:
uint8_t complementvar;
complementvar=~var;
~var
将计算为您期望的值,但是complementvar
具有类型uint8\t
,因此转换只会导致0xfc
在您的检查步骤中,这将再次升级为
int
,但由于uint8\u t
是一种无符号的类型,此处不进行符号扩展,只需添加0
位即可。这解释了xoring(^
)的结果。我建议您阅读以下内容:。即使这在这里也可能不是问题。@Scheff“虽然uint8\u t
被提升为unsigned
”,但两个uint8\u t
之间的操作可能会将它们转换/提升为int
,但没有符号扩展。(无符号字符或无符号短字符可以转换为int,如果它可以保持其整个值范围,则可以转换为int;否则,无符号int;)因此,uint8_t
^uint8_t
的结果是0xff
,即使0xff
的类型是(int)
,并且不等于-1
,至少是0xffff
(如果sizeof(int)
仅为2)。好的,现在我知道了。整数提升不会导致符号扩展。因此解决方案是(如果我想使用XOR操作以避免像我在@FelixPalmen的答案中写的那样显式转换为“基类型”)检查UINT8\u MAX
而不是-1
?@mbed\u dev然后您当然又被绑定到UINT8\u t
。我建议您阅读以下内容:。即使这可能不是问题。@Scheff“尽管UINT8\u t
被提升为未签名的
”两个uint8\t
s之间的操作可以将它们转换/升级为int
,但不带符号扩展。(如果无符号字符或无符号短字符可以保存其整个值范围,则可以将其转换为int;否则,则无符号int;)因此,即使0xff
的类型是(int)
,并且不等于-1
,至少0xffff
(在sizeof(int)
仅为2的情况下,uint8\u t
的结果是0xff
.好的,现在我明白了。整数提升不会导致符号扩展。因此解决方案是(如果我想使用XOR操作,以避免像我在@FelixPalmen的答案中所写的那样显式转换到“基类型”)将检查UINT8\u MAX
而不是-1
?@mbed\u dev然后您将再次绑定到UINT8\u t
。实际上,您版本的解决方案将是定义CHECKVAR(var,compl)((UINT8\u t)~var=(compl))
?,因为根据gcc
和MSVC++11
,compl
上的补码运算符的结果是0xffffff00
,因为补码运算符会导致与符号扩展相同的结果do@mbed_dev你说得对,该死的…我会把我的编辑回滚。我想你希望你的宏输入不可知论,我认为这是一种(有点聪明的)方法。它不是:实际上,您的版本的解决方案将是#define CHECKVAR(var,compl)(((uint8_t)~var)==(compl))
,因为根据gcc
和MSVC++11
在compl
上的补码运算符的结果是