2个指针,0字节差异但不相等 在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 ? } #包括 #包括 #包括 int main() { 长a=1; 长b=1; std::cout

2个指针,0字节差异但不相等 在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 ? } #包括 #包括 #包括 int main() { 长a=1; 长b=1; std::cout,c++,pointers,undefined-behavior,C++,Pointers,Undefined Behavior,很可能优化器注意到bPtr和aPlus8不可能相等,因此它将(bPtr==aPlus8)替换为false,以保存一些CPU指令 请注意,这种优化不仅仅是节省CPU指令——想象一下,如果您有 if(bPtr == aPlus8) { // lots of complicated code here } 然后优化器将能够删除if语句中的所有代码。这就是为什么此优化和类似优化非常有用的原因 实际上,在现代编译器上,未定义行为的主要影响之一是它允许优化器找到方法简化您意想不到的代码。优化器很可

很可能优化器注意到
bPtr
aPlus8
不可能相等,因此它将
(bPtr==aPlus8)
替换为
false
,以保存一些CPU指令

请注意,这种优化不仅仅是节省CPU指令——想象一下,如果您有

if(bPtr == aPlus8)
{
    // lots of complicated code here
}
然后优化器将能够删除
if
语句中的所有代码。这就是为什么此优化和类似优化非常有用的原因


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

优化器很可能注意到
bPtr
aPlus8
不可能相等,因此它取代了
(bPtr==aPlus8)
使用
false
保存一些CPU指令

请注意,这种优化不仅仅是节省CPU指令——想象一下,如果您有

if(bPtr == aPlus8)
{
    // lots of complicated code here
}
然后优化器将能够删除
if
语句中的所有代码。这就是为什么此优化和类似优化非常有用的原因


在实践中,在一个现代编译器中,未定义行为的主要影响之一是它允许优化器找到简化你没想到的代码的方法。

< P> C标准,并且可能是C++标准,明确地指出,如果两个指针可以“合法”。访问同一个对象时,它们将进行相等比较,并且还明确指出,指向一个对象的指针有时可能会与“刚刚经过”另一个对象的指针进行相等比较,即使它们不能合法地访问同一个对象。在大多数情况下,正确设计的代码不应该关心指向某个对象的指针是否会与另一个对象的指针进行相等比较“刚刚过去”是另一个标准,因此我认为这两个标准都没有明确说明:

  • 如果两个对象不相关,则一个刚过去的指针与另一个指针之间的每个单独比较都应被视为产生独立的未指定结果(意味着指针相等运算符不必表现为等价关系)

  • 未指定可通过“直接”和“刚刚过去”指针连接的不相关对象集,但涉及此类指针的比较将产生与某些此类集合一致的结果(意味着指针相等运算符将有效定义等价关系)

  • 指针相等的语义以某种方式定义,比#1更精确,但比#2更不精确


  • 该标准有意避免要求所有实现都适合系统编程,如果允许编译器进行所有涉及指向不相关对象的指针的比较,并报告它们不相等,那么编译器可能会生成更高效的代码。有一种标准的方法,用于编写代码,这将很有帮助就像系统编程可以指定它在没有标准规范之外通常不需要的语义保证的情况下工作,并且任何不能满足这种保证的实现都必须完全拒绝编译。我不知道C或C++中的任何方法都指定代码需要指针相等操作符来作为一个N等价关系,但C++有其他的指针比较方法,如<> > STD::,它提供了比它的操作符更强大的保证。

    < P> C标准,很可能是C++标准,明确地指出,如果两个指针可以“合法”。访问他们将比较相等的同一对象,并明确指出指向一个对象的指针有时可能与“刚刚过去”的指针比较相等另一个对象,即使它们不能合法地访问同一个对象。在大多数情况下,正确设计的代码不应该关心指向某个对象的指针是否会与“刚刚超过”另一个对象的指针相比较,因此我认为这两个标准都没有明确说明:

  • 如果两个对象不相关,则一个刚过去的指针与另一个指针之间的每个单独比较都应被视为产生独立的未指定结果(意味着指针相等运算符不必表现为等价关系)

  • 未指定可通过“直接”和“刚刚过去”指针连接的不相关对象集,但涉及此类指针的比较将产生与某些此类集合一致的结果(意味着指针相等运算符将有效定义等价关系)

  • 指针相等的语义以某种方式定义,比#1更精确,但比#2更不精确


  • 该标准有意避免要求所有实现都适合系统编程,如果允许编译器进行所有涉及指向不相关对象的指针的比较,并报告它们不相等,那么编译器可能会生成更高效的代码。有一种标准的方法,用于编写代码,这将很有帮助就像系统编程可以指定它在没有标准规范之外通常不需要的语义保证的情况下工作,并且任何不能满足这种保证的实现都必须完全拒绝编译。我不知道C或C++中的任何方法都指定代码需要指针相等操作符来作为一个n等价关系,C++ C++有其他的指针比较方法,如<>代码> STD:: >,它提供了比它的操作符更强的保证。< /P> C或C++。