对于一个指针p,在极端情况下p

时间:2022-12-25 21:43:22

Is it possible, for a pointer variable p, that p<(p+1) is false? Please explain your answer. If yes, under which circumstances can this happen?

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

I was wondering whether p+1 could overflow and be equal to 0.

我想知道p+1是否会溢出,等于0。

E.g. On a 64-bit PC with GCC-4.8 for a C-language program:

例如,在带有GCC-4.8的64位PC上运行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);
}

It returns:

它返回:

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

So I believe it is possible for this case. For an invalid pointer location it can happen. This is the only solution I can think of. Are there others?

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

Note: No assumptions are made. Consider any compiler/platform/architecture/OS where there is a chance that this can happen or not.

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

5 个解决方案

#1


44  

Is it possible, for a pointer variable p, that p<(p+1) is false?

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

If p points to a valid object (that is, one created according to the C++ object model) of the correct type, then no. p+1 will point to the memory location after that object, and will always compare greater than p.

如果p指向正确类型的有效对象(即根据c++对象模型创建的对象),则不会。p+1将指向该对象之后的内存位置,并且总是比p大。

Otherwise, the behaviour of both the arithmetic and the comparison are undefined, so the result could be true, false, or a suffusion of yellow.

否则,算术和比较的行为都是未定义的,所以结果可能是真、假或泛黄。

If yes, under which circumstances can this happen?

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

It might, or might not, happen with

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

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

If pointer arithmetic works like unsigned integer arithmetic, then this might cause a numeric overflow such that p+1 has the value zero, and compares less than p. Or it might do something else.

如果指针算法像无符号整数算法一样工作,那么这可能会导致数值溢出,使p+1的值为0,并且比较小于p。

#2


14  

What if I'm programming on DOS, and I have a far pointer (one composed of a segment and an offset), and it's pointing to the last address in the segment, and I add one to it, and the pointer wraps around? It looks like when you're comparing them, you normalize the pointers, so the second pointer p+1 would be less than p.

如果我在DOS上编程,我有一个远指针(一个由一个段和一个偏移量组成),它指向段中的最后一个地址,我给它添加一个,指针绕过去?当你比较它们的时候,你将指针规范化,所以第二个指针p+1会小于p。

This is a stab in the dark though, I don't have a DOS C compiler handy to test on.

这是一个暗处,我没有一个DOS C编译器可以测试。

#3


10  

Very simple: It cannot happen if there is no undefined behaviour involved. It can happen very easily in the presence of undefined behaviour. For details, read a copy of the C Standard or C++ Standard.

非常简单:如果没有未定义的行为,就不可能发生。这种情况很容易发生在没有定义的行为中。有关详细信息,请阅读C标准或c++标准的副本。

As a result, a conforming compiler is allowed to not evaluate the < operator at all and use 1 or true as the result instead. The same is true for arithmetic with signed integers (but not for unsigned integers, where it is possible for entirely legal code to have x > x+1).

因此,一个符合条件的编译器被允许完全不计算 <运算符,而是使用1或true作为结果。对于有符号整数的算术也一样(但对于无符号整数,完全合法的代码有可能有x> x+1)。

Your example code isn't even C or C++, so you seem to have used the compiler in a mode where it isn't a standard conforming C or C++ compiler.

您的示例代码甚至都不是C或c++,所以您似乎已经使用了编译器,它不是标准的兼容C或c++编译器。

#4


10  

It could happen with an invalid pointer.

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

But if the pointer points to a valid memory location, on many operating systems (e.g. Linux), it practically never happens (at least if the sizeof(*p) is not too big), because in practice the first and last pages of the address space are never mapped (but you could force a mapping with mmap & MAP_FIXED).

但如果指针指向一个有效的内存位置,在许多操作系统(如Linux),它几乎从来没有发生(至少如果sizeof(* p)不是太大),因为在实践中第一页和最后一页的地址空间是没有映射(但是你可能迫使一个映射mmap & MAP_FIXED)。

For freestanding implementations (i.e. inside a kernel, or on some microcontroller), things are different, and implementation specific (perhaps might be undefined behavior, or unspecified behavior).

对于独立的实现(例如在内核中,或者在一些微控制器上),事情是不同的,实现是特定的(可能是未定义的行为,或者未指定的行为)。

#5


3  

According to Pointer comparisons in C. Are they signed or unsigned? on Stack Overflow:

根据c中的指针比较,它们是有符号的还是无符号的?堆栈溢出:

You can't legally compare arbitrary pointers in C/C++. The result of such comparison is not defined.

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

#1


44  

Is it possible, for a pointer variable p, that p<(p+1) is false?

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

If p points to a valid object (that is, one created according to the C++ object model) of the correct type, then no. p+1 will point to the memory location after that object, and will always compare greater than p.

如果p指向正确类型的有效对象(即根据c++对象模型创建的对象),则不会。p+1将指向该对象之后的内存位置,并且总是比p大。

Otherwise, the behaviour of both the arithmetic and the comparison are undefined, so the result could be true, false, or a suffusion of yellow.

否则,算术和比较的行为都是未定义的,所以结果可能是真、假或泛黄。

If yes, under which circumstances can this happen?

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

It might, or might not, happen with

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

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

If pointer arithmetic works like unsigned integer arithmetic, then this might cause a numeric overflow such that p+1 has the value zero, and compares less than p. Or it might do something else.

如果指针算法像无符号整数算法一样工作,那么这可能会导致数值溢出,使p+1的值为0,并且比较小于p。

#2


14  

What if I'm programming on DOS, and I have a far pointer (one composed of a segment and an offset), and it's pointing to the last address in the segment, and I add one to it, and the pointer wraps around? It looks like when you're comparing them, you normalize the pointers, so the second pointer p+1 would be less than p.

如果我在DOS上编程,我有一个远指针(一个由一个段和一个偏移量组成),它指向段中的最后一个地址,我给它添加一个,指针绕过去?当你比较它们的时候,你将指针规范化,所以第二个指针p+1会小于p。

This is a stab in the dark though, I don't have a DOS C compiler handy to test on.

这是一个暗处,我没有一个DOS C编译器可以测试。

#3


10  

Very simple: It cannot happen if there is no undefined behaviour involved. It can happen very easily in the presence of undefined behaviour. For details, read a copy of the C Standard or C++ Standard.

非常简单:如果没有未定义的行为,就不可能发生。这种情况很容易发生在没有定义的行为中。有关详细信息,请阅读C标准或c++标准的副本。

As a result, a conforming compiler is allowed to not evaluate the < operator at all and use 1 or true as the result instead. The same is true for arithmetic with signed integers (but not for unsigned integers, where it is possible for entirely legal code to have x > x+1).

因此,一个符合条件的编译器被允许完全不计算 <运算符,而是使用1或true作为结果。对于有符号整数的算术也一样(但对于无符号整数,完全合法的代码有可能有x> x+1)。

Your example code isn't even C or C++, so you seem to have used the compiler in a mode where it isn't a standard conforming C or C++ compiler.

您的示例代码甚至都不是C或c++,所以您似乎已经使用了编译器,它不是标准的兼容C或c++编译器。

#4


10  

It could happen with an invalid pointer.

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

But if the pointer points to a valid memory location, on many operating systems (e.g. Linux), it practically never happens (at least if the sizeof(*p) is not too big), because in practice the first and last pages of the address space are never mapped (but you could force a mapping with mmap & MAP_FIXED).

但如果指针指向一个有效的内存位置,在许多操作系统(如Linux),它几乎从来没有发生(至少如果sizeof(* p)不是太大),因为在实践中第一页和最后一页的地址空间是没有映射(但是你可能迫使一个映射mmap & MAP_FIXED)。

For freestanding implementations (i.e. inside a kernel, or on some microcontroller), things are different, and implementation specific (perhaps might be undefined behavior, or unspecified behavior).

对于独立的实现(例如在内核中,或者在一些微控制器上),事情是不同的,实现是特定的(可能是未定义的行为,或者未指定的行为)。

#5


3  

According to Pointer comparisons in C. Are they signed or unsigned? on Stack Overflow:

根据c中的指针比较,它们是有符号的还是无符号的?堆栈溢出:

You can't legally compare arbitrary pointers in C/C++. The result of such comparison is not defined.

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