计算地址差异是未定义的行为吗?
Is calculating address difference undefined behaviour?
假设我执行以下操作:
void g(int* x)
{
int y = 0;
auto diff = uintptr_t(&y) - uintptr_t(x);
}
void f()
{
int x = 0;
g(&x);
}
diff
是否仅具有未定义的值,或者代码是否调用了未定义的行为?根据规范,代码是否保证很好地 运行 并计算 diff
的值,可能没有意义,或者它是否调用 UB?我相信有一些不相关的变量,但无法查明。
我对自(包括)C++ 11 以来的任何标准的答案感兴趣。
讨论来自以下评论:
将指针转换为足够大小的整数是明确定义的,从另一个整数中减去无符号整数是明确定义的,无论它们的值如何。这里没有未定义的行为。
而且,标准不保证转换后的整数有任何特定值,因此也不保证它们的减法结果。
引用C++11标准草案。关于将指针转换为整数
[expr.reinterpret.cast]
5 A value of integral type or enumeration type can be explicitly
converted to a pointer. A pointer converted to an integer of
sufficient size (if any such exists on the implementation) and back to
the same pointer type will have its original value; mappings between
pointers and integers are otherwise implementation-defined.
由于必须为要编译的代码定义 uintptr_t
,因此目标机器上存在一个整数类型,可以作为指针到整数转换的目标。映射是实现定义的,但最重要的是结果不是不确定的。这意味着您为两次转换都获得了一些有效的整数。
所以减法不是未定义的行为。但结果是实现定义的。
假设我执行以下操作:
void g(int* x)
{
int y = 0;
auto diff = uintptr_t(&y) - uintptr_t(x);
}
void f()
{
int x = 0;
g(&x);
}
diff
是否仅具有未定义的值,或者代码是否调用了未定义的行为?根据规范,代码是否保证很好地 运行 并计算 diff
的值,可能没有意义,或者它是否调用 UB?我相信有一些不相关的变量,但无法查明。
我对自(包括)C++ 11 以来的任何标准的答案感兴趣。
讨论来自以下评论:
将指针转换为足够大小的整数是明确定义的,从另一个整数中减去无符号整数是明确定义的,无论它们的值如何。这里没有未定义的行为。
而且,标准不保证转换后的整数有任何特定值,因此也不保证它们的减法结果。
引用C++11标准草案。关于将指针转换为整数
[expr.reinterpret.cast]
5 A value of integral type or enumeration type can be explicitly converted to a pointer. A pointer converted to an integer of sufficient size (if any such exists on the implementation) and back to the same pointer type will have its original value; mappings between pointers and integers are otherwise implementation-defined.
由于必须为要编译的代码定义 uintptr_t
,因此目标机器上存在一个整数类型,可以作为指针到整数转换的目标。映射是实现定义的,但最重要的是结果不是不确定的。这意味着您为两次转换都获得了一些有效的整数。
所以减法不是未定义的行为。但结果是实现定义的。