在C ++中,我充分意识到指针减法仅在数组中有效,并且下面的代码是未定义的行为。我知道试图对未定义的行为进行推理几乎是没有意义的,但是我认为提出以下问题是有价值的。

#include <cstddef>
#include <iostream>
#include <iomanip>

int main()
{
    long a = 1;
    long b = 1;

    std::cout << (char*)(&b) - (char*)(&a)  << '\n'; //prints 8, ok we're 8 bytes apart

    char* aPlus8 = (char*)&a + 8; //bump up 8 bytes
    char* bPtr = (char*)&b;

    std::cout << "diff in bytes = " << (bPtr - aPlus8)  << '\n';            //prints 0. All good, looks like we're there
    std::cout << "but are they the same? = " << (bPtr == aPlus8)  << '\n';  //but are we ?
}


最后一行bPtr == aPlus8返回false,尽管字节差为0。对此可能有解释吗? (除了“因为它是不确定的行为”)

这是用g++ -std=c++14 -O3 -Wall -pedantic编译的。如果我更改了优化级别,那么输出也会发生变化。

最佳答案

优化程序很可能注意到bPtraPlus8可能不相等,因此它用(bPtr == aPlus8)替换了false以保存一些CPU指令。

请注意,这种优化不仅可以节省CPU指令-想象一下您是否有类似的东西

if(bPtr == aPlus8)
{
    // lots of complicated code here
}


那么优化程序将能够删除if语句中的所有代码。这就是为什么此优化和类似优化有用的原因。

实际上,在现代编译器上,未定义行为的主要影响之一是,它使优化器可以找到简化您意想不到的代码的方法。

09-30 15:39