对于指针变量 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
所以我相信这种情况是可能的。对于无效的指针位置,它可能发生。 这是我能想到的唯一解决方案。还有其他人吗?
注意: 没有做出任何假设。考虑任何可能发生这种情况的编译器/平台/架构/操作系统。
答案 0 :(得分:44)
对于指针变量
p
,p<(p+1)
是否为假是否可能?
如果p
指向正确类型的有效对象(即根据C ++对象模型创建的对象),则为no。 p+1
将指向该对象之后的内存位置,并且将始终比大于p
。
否则,算术和比较的行为都是未定义的,因此结果可能是true,false或者是黄色。
如果是,在哪种情况下会发生这种情况?
可能会,也可能不会发生
p = reinterpret_cast<char*>(numeric_limits<uintptr_t>::max);
如果指针算法像无符号整数算术一样工作,那么这可能会导致数字溢出,使p+1
的值为零,并且比较小于p
。或者它可能会做其他事情。
答案 1 :(得分:14)
如果我在DOS上编程,我有一个far pointer(一个由一个段和一个偏移组成),它指向段中的最后一个地址,并且我添加一个,指针wraps around?看起来当你进行比较时,你会对指针进行规范化,因此第二个指针p+1
将小于p
。
这是在黑暗中刺伤,但我没有DOS C编译器方便测试。
答案 2 :(得分:10)
指针无效可能会发生。
但是如果指针指向有效的内存位置,在许多操作系统(例如Linux)上,几乎不会发生(至少如果sizeof(*p)
不是太大),因为在实践中地址空间的第一页和最后一页从未映射过(但您可以使用mmap
&amp; MAP_FIXED
强制映射。
对于独立实现(即内部内核或某些微控制器),事情是不同的,具体实现(可能是undefined behavior或unspecified behavior)。
答案 3 :(得分:10)
非常简单:如果不涉及未定义的行为,则不会发生这种情况。在存在未定义的行为时,它很容易发生。有关详细信息,请阅读C标准或C ++标准的副本。
结果,允许符合标准的编译器不评估&lt;运算符,并使用1或true作为结果。具有有符号整数的算术也是如此(但对于无符号整数,完全合法的代码可能使x> x + 1)。
您的示例代码甚至不是C或C ++,因此您似乎在不是标准符合C或C ++编译器的模式下使用了编译器。
答案 4 :(得分:3)
根据Stack Overflow上的Pointer comparisons in C. Are they signed or unsigned?:
您无法合法地比较C / C ++中的任意指针。这种比较的结果没有定义。