【问题标题】:Bitwise Negation Issue - C (Tiva C TM4C123GXL)按位求反问题 - C (Tiva C TM4C123GXL)
【发布时间】:2022-03-25 01:44:36
【问题描述】:

在使用 TM4C123GXL 时,我遇到了一个奇怪的行为,我认为这归因于编译器。 (TI v20.2.5.LTS) 将按位求反函数与等价运算符结合使用时,编译器似乎没有正确遵循操作顺序。

本质上,您会发现选项#1 将不起作用,即使它应该是正确的(据我所见)也会导致错误。但是,选项 #2 将起作用并将结果为真。 (据我所知,这与不必要的变量声明相同)

选项#1(应该有效,但无效)

    uint8_t foo = 0x40; // 0100 0000
    uint8_t fooinv = 0xBF; // 1011 1111
    uint8_t bar = 0x04; // 0000 0100
    uint8_t barinv = 0xFB; // 1101 1111
    bool valid = true;
    valid = (foo == ~fooinv) && valid;
    valid = (bar == ~barinv) && valid;

选项#2(额外变量但有效)

    uint8_t foo = 0x40; // 0100 0000
    uint8_t fooinv = 0xBF; // 1011 1111
    uint8_t bar = 0x04; // 0000 0100
    uint8_t barinv = 0xFB; // 1101 1111
    uint8_t temp1 = ~fooinv;
    uint8_t temp2 = ~barinv;
    bool valid = true;
    valid = (foo == temp1) && valid;
    valid = (bar == temp2) && valid;

我怀疑这是因为可能存在某种未解决的数据危害,但我无法确定这里发生了什么。我还没有反汇编编译器创建的代码,但感谢您提供任何帮助。

    标签: c bit-manipulation bitwise-operators


    【解决方案1】:

    ~ 的行为在 C 2018 6.5.3.3 4 中指定,其中包括:

    ... 整数提升在操作数上执行,结果具有提升的类型...

    整数提升将uint8_t 转换为int。因此,在~fooinv 中,fooinv 的值0xBF 被转换为int。这不会改变值;它仍然是0x000000BF,它是相同的值,只是显示了更多位。 (对于这个答案,我将使用 32 位 int,这在 C 实现中目前很常见。)然后执行按位否定会产生 0xFFFFFF40。这与foo0x40 的值不同,所以foo == ~fooinv 当然会产生假(零)。

    如果您想计算fooinv 的按位否定在uint8_t 中的值,您可以简单地转换结果:(uint8_t) ~fooinv。比较foo == (uint8_t) ~fooinv 产生真(一)。

    【讨论】:

      【解决方案2】:

      问题是在这些表达式中

      valid = (foo == ~fooinv) && valid;
      valid = (bar == ~barinv) && valid;
      

      使用整数提升将像这样的操作数~fooinv 转换为类型int。所以实际上你正在处理值 = 0xFFFFFF40

      来自 C 标准(6.5.3.3 一元算术运算符)

      4 ~ 运算符的结果是它的按位补码 (提升)操作数(即,结果中的每一位都被设置当且仅 如果未设置转换后的操作数中的相应位)。这 对操作数执行整数提升, 结果有 提升的类型。如果提升的类型是无符号类型,则 表达式 ~E 等价于可表示的最大值 键入减 E。

      所以要得到预期的结果,你应该写

      valid = (foo == ( uint8_t  )~fooinv) && valid;
      valid = (bar == ( uint8_t  )~barinv) && valid;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-12
        • 1970-01-01
        相关资源
        最近更新 更多