2个指针,0个字节的差异但不相等

Pow*_*ice 0 c++ pointers undefined-behavior

在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 ?
}
Run Code Online (Sandbox Code Playgroud)

最后一行bPtr == aPlus8返回false,尽管字节差异为0.是否可能有此解释?(除了"因为它是未定义的行为")

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

use*_*751 6

最有可能的优化注意到,bPtraPlus8不可能是平等的,所以它取代(bPtr == aPlus8)false节省一些CPU指令.

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

if(bPtr == aPlus8)
{
    // lots of complicated code here
}
Run Code Online (Sandbox Code Playgroud)

然后优化器将能够删除if语句中的所有代码.这就是为什么这种优化和类似的优化是有用的.

实际上,在现代编译器中,未定义行为的主要影响之一是它允许优化器找到简化代码的方法.