Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 对超出范围指针的比较是否定义良好?_C++_Language Lawyer - Fatal编程技术网

C++ 对超出范围指针的比较是否定义良好?

C++ 对超出范围指针的比较是否定义良好?,c++,language-lawyer,C++,Language Lawyer,给定以下代码: char缓冲区[1024]; char*const begin=缓冲区; char*const end=buffer+1024; char*p=begin+2000; 如果(pend) std::能否结束)定义良好?或者该代码是否具有未定义的行为,因为指针已前进到数组末尾 如果比较定义良好,那么定义是什么 (额外积分:对begin+2000本身的求值是否未定义行为?对begin+2000的求值未定义,它将经过数组的末尾-您可以在数组的末尾上一个,但不能再上一个 根据C++11§5

给定以下代码:

char缓冲区[1024];
char*const begin=缓冲区;
char*const end=buffer+1024;
char*p=begin+2000;
如果(pend)
std::能否结束
)定义良好?或者该代码是否具有未定义的行为,因为指针已前进到数组末尾

如果比较定义良好,那么定义是什么


(额外积分:对
begin+2000
本身的求值是否未定义行为?

begin+2000
的求值未定义,它将经过数组的末尾-您可以在数组的末尾上一个,但不能再上一个

根据C++11§5.7/5加法运算符:

将具有整数类型的表达式添加到指针或从指针中减去时,结果具有指针操作数的类型。如果指针操作数指向数组对象的某个元素,且数组足够大,则结果将指向与原始元素偏移的元素,以便生成的数组元素与原始数组元素的下标之差等于整数表达式。[…]如果指针操作数和结果都指向同一数组对象的元素,或超过数组对象最后一个元素的元素,则计算不应产生溢出否则,该行为为 未定义

对于要指定的指针比较,假设您有有效的指针开始,它们基本上需要是指向同一数组(或结束后的数组)的指针,或指向同一对象的同一访问控制的非静态数据成员的指针(除非它是并集…)

详情见§5.9/2关系运算符:

可以比较指向相同类型的对象或函数的指针(指针转换后),结果定义如下:

  • 如果同一类型的两个指针p和q指向同一个对象或函数,或者都指向一个过去 相同数组的结尾,或都为null,则p=q都产生true和pq 两者都是错误的
  • 如果同一类型的两个指针p和q指向不同的对象,而这些对象不是同一类型的成员 同一数组或不同函数的一个或多个元素,或者如果其中只有一个为null,则返回结果 对于pq,p=q未指定
  • 如果两个指针指向同一对象的非静态数据成员,或指向子对象或数组元素 在这些成员中,如果 两个成员具有相同的访问控制(第11条),前提是他们的类不是联合体
  • 如果两个指针指向具有不同访问控制的同一对象的非静态数据成员 (第11条)结果未指明。 -如果两个指针指向同一union对象的非静态数据成员,则它们的比较相等(在 如有必要,转换为void*)。如果两个指针指向同一数组中的元素或一个以上的元素 数组的末尾,指向下标越高的对象的指针越高
  • 未指定其他指针比较
我将采用标准。根据第5.7节(加法操作数)第5段,在进行比较之前,
*p=begin+2000
的行为首先是未定义的:

如果指针操作数和结果都指向 相同的数组对象,或数组对象的最后一个元素后一个, 评估不得产生过流;否则,行为 未定义


程序的行为未定义,但不是因为比较

表达式
begin+2000
的计算具有未定义的行为,因为结果将指向超过1024个元素数组末尾的多个元素

引用C++11(实际上是草案),5.7p4[expr.add]:

当对具有整数类型的表达式进行加法或减法运算时 对于指针,结果具有指针操作数的类型。[...] 如果指针操作数和结果都指向 相同的数组对象,或数组对象的最后一个元素后一个, 评估不得产生溢出;否则,行为 没有定义


简而言之,仅仅计算一个越界指针就有未定义的行为;在那之后对指针执行什么操作无关紧要。

我认为答案只不过是指针一过结束和NULL,但我不能引用章节。在具有分段内存的系统上,地址
begin+2000
可能不存在。这个问题有两个不同的概念:指针的比较,以及指针值的创建。在询问指针比较之前,我们必须确定
begin+2000
是否定义良好。我想不是。一旦我们有了两个有效的指针,您就可以询问如何比较它们。作为Mat的答题说明,一般情况下没有具体说明。然而,您可以使用
std::less
(等)来获得指针值的总顺序,即使使用
来解释原因,也可以想象
缓冲区可以分配在只有2048字节大的内存中的地址500处。所以
begin
将是500,而
p
将是2500。但由于内存只有2048大(因此指针只有11位长),因此
p
实际得到的是地址452——在
缓冲区之前。(是的,这个例子是人为设计的,但是有各种实际的分段内存模式,它们没有那么大的不同。)注意,您可以使用
std::less
(等)来获得无关指针的总排序(当然,它们必须仍然具有有效值,这是一个完全不同的事情)。但是当然“排序”不相关的指针在很大程度上是没有意义的,因为它没有指向任何东西。没有什么“在那里”,这是无效的