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
  • 将异或运算的结果与-1(表示为整数)一起检查
    1111111111111111111111111111111111111111111111==1111111111111111111111111111111111111111
    的结果应该是true,但我总是收到false,因为异或运算的结果(对我来说很奇怪)是0x000000ff
  • 我用的是什么编译器?它是MSVC++11,但实际上解决方案应该尽可能独立于编译器。 由于我也必须是可移植的,使用C编译器的结果会不同吗

    补码运算后,complementvar的值为
    0xfffffffc

    不,看看这个代码:

    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
    上的补码运算符的结果是