dou*_*oug 3 c++ pointers pointer-arithmetic language-lawyer
可以比较指向类成员变量的指针,结果取决于声明顺序。请参阅规范例如,编译器资源管理器中的此示例有效并返回 true (1):
struct A {
int a0 = 1;
int a1 = 2;
};
consteval int foo()
{
A a;
int* p1 = &a.a0;
int* p2 = &a.a1;
return p2 > p1;
}
int main()
{
return foo();
}
Run Code Online (Sandbox Code Playgroud)
因此,人们会期望它p2-p1会返回指针之间的距离(以 int 对象为单位)。它在运行时执行。编译器浏览器
struct A {
int a0 = 1;
int a1 = 2;
};
int foo()
{
A a;
int* p1 = &a.a0;
int* p2 = &a.a1;
return p2 - p1;
}
int main()
{
return foo();
}
Run Code Online (Sandbox Code Playgroud)
但不是在编译时。GCC、CLANG 和 MSVC 的行为都不同。GCC 编译并返回预期值,CLANG 抱怨 UB,MSVC 编译但返回 4,而不是 1,以字节为单位的距离!编译器资源管理器
CLANG:注意:相减的指针不是同一数组的元素
哪个是对的?
Rya*_*ing 14
您不能减去指向对象的指针,除非它们是同一数组的元素。这是未定义的行为,因此您可以获得不同的结果。
\n\n\n如果 P 和 Q 分别指向同一数组对象 x 的数组元素 i 和 j,则表达式 P - Q 的值为 i \xe2\x88\x92 j。
\n否则,行为是未定义的。
\n
http://eel.is/c++draft/expr.add#5.2
\nclang 将其标记为未定义行为是正确的,gcc 和 msvc 做任何他们想做的事情是正确的,因为它是未定义的行为。如果该函数consteval只有 clang 是正确的,其他函数应该发出诊断