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
, thatp<(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
, thatp<(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++中,不能合法地比较任意指针。这种比较的结果没有定义。