Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.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++_C_Pointers_Language Lawyer_Pointer Arithmetic - Fatal编程技术网

C++ 指针运算或比较限制的基本原理是什么?

C++ 指针运算或比较限制的基本原理是什么?,c++,c,pointers,language-lawyer,pointer-arithmetic,C++,C,Pointers,Language Lawyer,Pointer Arithmetic,在C/C++中,仅当结果指针位于原始指针内时才定义。此外,只有当两个指针对象是唯一完整对象的子对象时,才能执行两个指针的匹配 这些限制的原因是什么 我认为分段内存模型(见§1.2.1)可能是原因之一,但由于编译器实际上可以定义所有指针的总顺序,如本文所示,我对此表示怀疑。原因是保持生成合理代码的可能性。这适用于具有平面内存模型的系统以及具有更复杂内存模型的系统。如果禁止(不是很有用的)角点情况,如数组的加减和对象之间指针的总顺序,则可以在生成的代码中跳过大量开销 该标准施加的限制允许编译器对指针

在C/C++中,仅当结果指针位于原始指针内时才定义。此外,只有当两个指针对象是唯一完整对象的子对象时,才能执行两个指针的匹配

这些限制的原因是什么


我认为分段内存模型(见§1.2.1)可能是原因之一,但由于编译器实际上可以定义所有指针的总顺序,如本文所示,我对此表示怀疑。

原因是保持生成合理代码的可能性。这适用于具有平面内存模型的系统以及具有更复杂内存模型的系统。如果禁止(不是很有用的)角点情况,如数组的加减和对象之间指针的总顺序,则可以在生成的代码中跳过大量开销


该标准施加的限制允许编译器对指针算法进行假设,并使用该假设来提高代码质量。它包括在编译器中静态计算而不是在运行时计算,以及选择要使用的指令和寻址模式。举个例子,考虑一个带有两个指针的程序:代码> P1<代码>和<代码> P2 < /代码>。如果编译器可以推导出它们指向不同的数据对象,那么它可以安全地假设任何基于以下
p1
的操作都不会影响
p2
指向的对象。这允许编译器根据<代码> P1 < /code >重新排序加载和存储,而不考虑基于<代码> P2 < /code >的另一种方式的加载和存储。

< p>您只证明限制可以被移除,但忽略了它会以成本(在内存和代码方面)来产生,这与C.

的目标相反。 具体来说,差异需要有一个类型,即ptrdiff_t,我们可以假设它与size_t相似

在分段记忆模型中,你(通常)间接地对对象的大小有限制——假设:中的答案是正确的

因此,至少对于差异而言,取消该限制不仅会增加额外指令以确保总订单——对于不重要的角落案例(如其他答案所示),而且会花费两倍于差异的内存量等

C语言被设计成更简约的语言,而不是强迫编译器在这种情况下花费内存和代码。(在那些日子里,内存限制更为重要。)


显然还有其他好处——比如在混合来自不同数组的指针时检测错误的可能性。类似地,两个不同容器的混合迭代器在C++中是未定义的(有一些例外)-一些调试实现检测到这些错误。

< P>有程序和数据空间被分离的体系结构,并且根本不可能减去两个任意指针。指向函数或常量静态数据的指针将位于与普通变量完全不同的地址空间中


即使您任意提供了不同地址空间之间的排序,也有可能
diff\u t
类型需要更大的大小。比较或减去两个指针的过程会非常复杂。对于一种专为速度而设计的语言来说,这不是一个好主意。

其基本原理是,某些体系结构具有分段内存,指向不同对象的指针可能指向不同的内存段。这两个指针之间的差异不一定是有意义的

这可以追溯到标准C之前。C的基本原理没有明确提到这一点,但如果我们看看它解释了为什么使用负数组索引是未定义行为的基本原理(C99基本原理5.10 6.5.6,重点):

另一方面,在p-1的情况下,整个对象必须在分配之前分配 p遍历的对象数组,因此从数组底部运行的递减循环可能会失败。 此限制允许分段体系结构,例如,将对象放置在 可寻址内存的范围。


由于C标准旨在涵盖大多数处理器体系结构,因此还应涵盖以下体系结构:
想象一下一个架构(我知道一个,但不想命名),其中指针不仅仅是简单的数字,而是类似于结构或“描述符”。这种结构包含有关它指向的对象(其虚拟地址和大小)及其内部偏移量的信息。添加或减去指针会生成一个新的结构,只调整偏移字段;禁止生成偏移量大于对象大小的结构。还有其他限制(如初始描述符的生成方式或修改它的其他方式),但它们与主题无关。

我想通过颠倒问题来回答这个问题。与其问为什么不允许指针加法和大多数算术运算,为什么指针只允许对指向同一数组的指针加减整数、前后加减量和比较(或减法)?这与算术运算的逻辑结果有关。 在指针p上加/减一个整数n,可以得到当前指向元素的第n个元素的正向或反向地址。类似地,减去指向同一数组的p1和p2可以得到两个指针之间的元素计数。
指针算术运算的定义与其所指向的变量类型一致,这一事实(或设计)真是天才之举。除允许的操作外,任何操作都违反编程或哲学逻辑推理,因此不允许进行。

在大多数情况下,如果STANARD cla