首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >指针在C++中是否被视为无符号值?

指针在C++中是否被视为无符号值?
EN

Stack Overflow用户
提问于 2018-01-24 18:11:07
回答 3查看 1.5K关注 0票数 1

签名溢出未定义。无符号溢出被定义为模块化算法。

因此,我的问题是,下列定义或未定义:

代码语言:javascript
复制
#include <assert.h>
#include <cstdint>

struct X { int x;/* ... anything ... */ };

X array[3] = { 2, 3, 4 /* or other init values that is compatible with X */};
X* element = array + 1;

std::uintptr_t plus1 = 1;
std::uintptr_t minus1 = 0-plus1;


int main()
{
    printf("%p\n%p\n", element + plus1, array + 2);
    printf("\n");
    printf("%p\n%p\n", element + minus1, array);
    assert(element + plus1 == array + 2);
    assert(element + minus1 == array);
}

虽然我声明了plus1/minus1,但实际上我的意思是任何+/-值。如果我正确理解它,这应该是可行的。我说的对吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-01-24 18:29:27

在抽象机器中定义指针算法。

在抽象机器中,只有当ptr+x存在于对象中,使其地址位于边缘的-x中时,ptr才是有效的。

此抽象机器不关心指针或有符号整数或无符号整数的特定大小。在此抽象机器中,有符号整数和无符号整数的值为实整数或未指定的值。

具有32位minus1uintptr_t等于0 0xffffffff,这是一个大的正整数。

element是否指向一个大到足以使0 0xffffffff*sizeof(X)稍后仍在对象内的对象内?不,不需要。

因此,element+minus1是一个未定义的操作。任何事都有可能发生。

在您的硬件上,将指针算法简单地插入到机器代码中可能会导致它被包围。但依靠这个并不安全。

首先,优化者有时喜欢证明事实。如果它们证明element大于array的地址,那么任何对element的无符号加法都不可能使其与array相等,因此编译器可以将element+unsigned value == array优化为false

如果您更改优化设置、升级编译器或完全无害的事情(如内联的更改)、内联的其他代码、链接时间优化时的启发式或月亮的变化阶段,就会发生这样的优化。

依赖于它的工作是危险的,即使是这样,因为您现在开始负责审计它生成的机器代码,而不是源代码。

票数 3
EN

Stack Overflow用户

发布于 2018-01-24 18:19:41

指针算法只有在所涉及的指针保持在单个数组对象内或仅在数组结束后才能很好地定义。所以从技术上讲,表达式element + minus1是未定义的行为--因为minus1是一个非常大的值,它运行在数组的末尾。

现在,在实践中,这可能是可行的,但在技术上仍未定义。

票数 3
EN

Stack Overflow用户

发布于 2018-01-24 18:16:15

  • std::uintptr_t是一个无符号积分。
  • std::intptr_t是一个有符号的积分。

因此定义了std::uintptr_t溢出,而std::intptr_t溢出导致UB。

此外,指针算法仅在数组中有效(指向数组结束后的一个数组)。

minus1std::uintptr_t能容纳的最大数字。

来自arithmetic

  • 如果指针P指向数组的ith元素,则表达式P+n、n+P和P+n是指向同一数组的i+nth、i+nth和ith元素的相同类型的指针。指针加法的结果也可能是一个过结束指针(即指针P,使得表达式P1指向数组的最后一个元素)。任何其他情况(即,试图生成不指向同一数组或结束后的元素的指针)都会调用未定义的行为。

element + minus1element - 1不一样。

element + minus1在数组的有效范围之外,因此导致UB。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48429021

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档