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

问题描述 投票:47回答:5

对于指针变量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);
}

它返回:

p      : 0xffffffffffffffff
p+1    : (nil)
Result : 0

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

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

c++ c pointers pointer-arithmetic
5个回答
44
投票

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

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

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

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

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

p = reinterpret_cast<char*>(numeric_limits<uintptr_t>::max);

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


14
投票

如果我在DOS上编程,我有一个far pointer(一个由一个段和一个偏移组成),它指向段中的最后一个地址,我加一个,指针wraps around怎么办?看起来当你比较它们时,你会对指针进行标准化,所以第二个指针p+1将小于p

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


10
投票

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

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

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


10
投票

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

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

对于独立实现(即在内核内或在某些微控制器上),事情是不同的,并且具体实现(可能是undefined behaviorunspecified behavior)。


3
投票

根据堆栈溢出的Pointer comparisons in C. Are they signed or unsigned?

您不能合法地比较C / C ++中的任意指针。这种比较的结果没有定义。

© www.soinside.com 2019 - 2024. All rights reserved.