计算地址差异是未定义的行为吗?

Jef*_*ica 7 c++ language-lawyer c++11

假设我执行以下操作:

void g(int* x)
{
    int y = 0;
    auto diff = uintptr_t(&y) - uintptr_t(x);
}

void f()
{
    int x = 0;
    g(&x);
}
Run Code Online (Sandbox Code Playgroud)

难道diff仅仅是有明确的值,或确实发生未定义行为的代码?根据规范,代码是否保证运行良好并计算 的值diff,可能没有意义,还是调用 UB?我相信有一些关于不相关变量的东西,但无法确定它。

我对自(包括)C++ 11 以来的任何标准的答案感兴趣。

讨论来自以下评论:C++ 中的打印堆栈

Sto*_*ica 8

引用 C++11 标准草案。关于将指针转换为整数的主题

[expr.reinterpret.cast]

5整数类型或枚举类型的值可以显式转换为指针。一个指针转换为一个足够大的整数(如果实现中存在这样的整数)并返回到相同的指针类型将具有其原始值;指针和整数之间的映射是由实现定义的。

由于uintptr_t必须为要编译的代码定义,因此目标机器上存在一个整数类型,可以作为指针到整数转换的目标。映射是实现定义的,但最重要的是结果不是不确定的。这意味着您为两种转换都获得了一些有效的整数。

所以减法不是未定义的行为。但结果是实现定义的。


eer*_*ika 5

将指针转换为足够大小的整数是明确定义的,从另一个中减去无符号整数是明确定义的,无论它们的值如何。这里没有未定义的行为。

而且,标准不保证转换后的整数的任何特定值,因此也不保证它们的减法结果。