![]() |
1
19
我认为你是对的,不可能实现
我认为,测试区域是否重叠的唯一真正可移植的方法是这样的:
[编辑:以后再看,我想应该是
你也不能实现
C++引入指针专业化
C没有这样的东西,所以从某种意义上说,C++标准同意C没有足够定义的行为。但是,C++需要它
|
![]() |
2
7
对于两个有效且重叠的内存区域,我相信您需要处于6.5.8.5中定义的情况之一。也就是说,数组、联合、结构等的两个区域。 其他情况未定义的原因是两个不同的对象甚至可能不在同一类型的内存中,具有相同类型的指针。在PC体系结构中,地址通常只是虚拟内存中的32位地址,但是C支持各种奇怪的体系结构,在这些体系结构中,内存不是这样的。 C不定义事物的原因是在不需要定义情况时给编译器编写者让路。阅读6.5.8.5的方法是一个段落,它详细描述了C想要支持的体系结构,如果指针比较没有意义,除非它在同一个对象中。 另外,编译器提供memmove和memcpy的原因是,它们有时使用专门的指令编写在目标CPU的调优程序集中。它们并不意味着能够以相同的效率在C中实现。 |
![]() |
3
2
首先,C标准因在细节方面存在问题而臭名昭著。部分问题是因为C用于多个平台,并且标准尝试足够抽象以涵盖所有当前和未来的平台(这可能使用一些复杂的内存布局,这是我们从未见过的)。为了让编译器编写者为目标平台“做正确的事情”,有许多未定义的或特定于实现的行为。包含每个平台的详细信息是不切实际的(而且经常过时);相反,C标准将其留给编译器编写者来记录在这些情况下发生的事情。”“未指定”行为只意味着C标准没有指定发生了什么,不一定是无法预测结果。如果您阅读目标平台和编译器的文档,结果通常仍然是可预测的。 由于确定两个指针是否指向同一个块、内存段或地址空间取决于该平台的内存布局方式,所以规范没有定义进行该确定的方法。它假定编译器知道如何做出这个决定。您引用的规范部分说,指针比较的结果取决于指针的“地址空间中的相对位置”。注意,“地址空间”在这里是单数。本节仅指位于同一地址空间中的指针;即直接可比较的指针。如果指针位于不同的地址空间中,那么结果将由C标准定义,而不是由目标平台的要求定义。
在情况下
总之,C标准有很多故意未指定的地方,因为它不能在任何目标平台上编写一个简单的规则。然而,标准作家本可以做得更好的解释 为什么 有些东西没有被定义和使用更具描述性的术语,比如“依赖于体系结构”。 |
![]() |
4
1
这是另一个想法,但我不知道它是否正确。避免
我不确定这个交换性是不是由标准定义的,但是它是有意义的,因为它是有效的,即使指针的低位是一个实际的数字地址,高位是某种黑盒。 |
![]() |
5
0
但这不是证据。绝对无法保证您可以比较任意机器体系结构上的两个任意指针。这种指针比较的行为不能由C标准甚至编译器来规定。我可以想象一台具有分段结构的机器,它可能会根据段在RAM中的组织方式产生不同的结果,甚至可能在比较不同段中的指针时选择抛出异常。这就是行为“未定义”的原因。在完全相同的机器上运行完全相同的程序可能会在运行到运行之间产生不同的结果。 memmove()的经常给出的“解决方案”使用两个指针的关系来选择是从开始复制到结束还是从结束复制到开始只有在所有内存块都从相同的地址空间分配时才有效。幸运的是,这种情况通常是这样的,尽管它不是在16位x86代码的时代。 |
![]() |
Xirema · 如何正确编写运算符的R值重载 7 年前 |
![]() |
Mário Feroldi · 在运行时调用代码中未调用的函数 7 年前 |
![]() |
chqrlie · 所有位0都可以是整数的陷阱表示吗? 7 年前 |
![]() |
Vincent · 打印零,但不基于该条件退出循环 7 年前 |
![]() |
Dror K. · 用%p打印空指针是未定义的行为? 7 年前 |
![]() |
Bite Bytes · C中允许这种函数调用吗 7 年前 |
![]() |
K J Gor · C中strncpy的内存混淆 8 年前 |