在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
编译的。如果我更改了优化级别,那么输出也会发生变化。 最佳答案
优化程序很可能注意到bPtr
和aPlus8
可能不相等,因此它用(bPtr == aPlus8)
替换了false
以保存一些CPU指令。
请注意,这种优化不仅可以节省CPU指令-想象一下您是否有类似的东西
if(bPtr == aPlus8)
{
// lots of complicated code here
}
那么优化程序将能够删除
if
语句中的所有代码。这就是为什么此优化和类似优化有用的原因。实际上,在现代编译器上,未定义行为的主要影响之一是,它使优化器可以找到简化您意想不到的代码的方法。