当C指标同时指向同一数组的元素时,C标准保证了指针比较的有效性,但通常如何在系统中确保它?
编译器可能允许您在有符号和无符号指针之间进行选择。编译器将生成进行比较的程序集。但编译器不分配内存。例如,如果使用签名指针进行编译,编译器如何知道运行时不会为跨越签名溢出中断的数组分配块?
答案 0 :(得分:1)
编译器可能允许您在有符号和无符号指针之间进行选择。编译器将生成进行比较的程序集。但编译器不分配内存。例如,如果使用签名指针进行编译,编译器如何知道运行时不会为跨越签名溢出中断的数组分配块?
换句话说,典型实现如何确保没有用户数据跨越地址0x80000000
或0x00000000
。好吧,在流行的桌面操作系统上,你可以免费获得这个保证,因为0x00000000
在内核空间(你的用户空间程序无法访问)而且0x80000000
是......好吧,我实际上并不是这样的了解32位机器了。但是在64位计算机上,0x8000000000000000
实际上处于中间位置 - 典型的64位操作系统不会在0x0000FFFFFFFFFFFF
之间的巨大范围内映射任何和0xFFFF000000000000
(source)。如果你有大量的资源,那么将几十亿字节闲置就没有问题。 (大量低调警告!)
现在,如果您使用裸机编程,那么您可能 保证&a[7] < &a[8]
。如果您在RISC目标(如PowerPC或V800)上进行编程并利用位于地址0x0000
周围的“小数据区”(由于从这些地址加载,可以快速访问),这种情况尤其如此。不要求间接通过寄存器)。在这种情况下,您基本上鼓励编译器在0x0000
边界上拆分变量(更糟糕的是,允许&v == NULL
为真),以换取有价值的优化。
答案 1 :(得分:0)
没有机制可以在C中强制执行此类正确性。由您来编写正确的代码。 C不是一种安全的语言。可以编写不构成有效程序的语法正确的代码。
答案 2 :(得分:0)
AFAIK,内存地址始终使用无符号。如果你的代码使用了它们,那么它就不会运行良好(除非你真的知道你在做什么)。