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