对于指针p,在极端情况下p <p + 1是否可以为假?

aka*_*tis 47 c c++ pointers pointer-arithmetic

对于指针变量p,p <(p + 1)是否为假是否可能?请解释一下你的答案.如果是,在哪种情况下会发生这种情况?

我想知道p + 1是否会溢出并且等于0.

例如,在64位PC上使用GCC-4.8进行C语言程序:

int main(void) {
   void *p=(void *)0xFFFFFFFFFFFFFFFF;

   printf("p      :%p\n", p);
   printf("p+1    :%p\n", p+1);
   printf("Result :%d\n", p<p+1);
}
Run Code Online (Sandbox Code Playgroud)

它返回:

p      : 0xffffffffffffffff
p+1    : (nil)
Result : 0
Run Code Online (Sandbox Code Playgroud)

所以我相信这种情况是可能的.对于无效的指针位置,它可能发生.这是我能想到的唯一解决方案.还有其他人吗?

注意: 不做任何假设.考虑任何可能发生这种情况的编译器/平台/架构/操作系统.

Mik*_*our 44

对于指针变量p,它是否可能p<(p+1)是假的?

如果p指向正确类型的有效对象(即根据C++对象模型创建的对象),则为no.p+1将指向该对象之后的内存位置,并将始终比较大于p.

否则,算术和比较的行为都是未定义的,因此结果可能是true,false或者是黄色.

如果是,在哪种情况下会发生这种情况?

它可能会,也可能不会发生

p = reinterpret_cast<char*>(numeric_limits<uintptr_t>::max);
Run Code Online (Sandbox Code Playgroud)

如果指针算法像无符号整数算术一样工作,那么这可能会导致数值溢出,p+1其值为零,并且比较小于p.或者它可能会做其他事情.

  • "黄色的积聚"仅适用于> 4的值. (7认同)

dso*_*ano 14

如果我在DOS上编程,并且我有一个远指针(一个由一个段和一个偏移组成),它指向段中的最后一个地址,我向它添加一个,并且指针环绕?看起来当你比较它们时,你会规范化指针,所以第二个指针p+1会小于p.

这是一个在黑暗中刺,但我没有DOS C编译器方便测试.

  • 不是完全.根据内存模型,您可以拥有超出分段边界的对象.在`huge`内存模型中,将指针递增到段中的最后一个地址是有效的,因为那里的数组可以跨越段边界.这意味着编译器必须检查溢出并相应地调整段部分.使用未分段的指针,你无法绕过`nullptr`. (3认同)

Bas*_*tch 10

它可能发生在无效指针上.

但是,如果指针指向有效的内存位置,在许多操作系统(例如Linux)上,它几乎从未发生过(至少如果sizeof(*p)不是太大),因为在实践中,地址空间的第一页和最后一页从未映射过(但您可以使用mmap&MAP_FIXED)强制映射.

对于独立实现(即内核或在某些微控制器上),事情是不同的,特定于实现(可能是未定义的行为,或未指定的行为).


gna*_*729 10

很简单:如果没有涉及未定义的行为,就不会发生这种情况.在存在未定义的行为时,它很容易发生.有关详细信息,请阅读C标准或C++标准的副本.

因此,允许符合标准的编译器根本不评估<运算符,而是使用1或true作为结果.具有有符号整数的算术也是如此(但对于无符号整数,完全合法的代码可能使x> x + 1).

您的示例代码甚至不是C或C++,因此您似乎在不是标准符合C或C++编译器的模式下使用了编译器.