我在看为什么可以';你不在C中对指针进行逐位运算吗?有办法解决这个问题吗?并注意到,大多数响应都说,由于指针在标准中没有很好地定义,所以对指针的逐位操作没有很好的定义。然而,在我的任何系统类中都从未出现过这种情况,我也不知道指针可以是指针所指向的内存地址的值。有没有C的任何实现中,指针不表示为指针所指的内存地址?
有没有计划改变这一点,以便在未来的C标准中很好地定义指针?
这里绝对没有问题:
-
您想对指针执行逐位操作吗?
你引用的链接给出了一个常见的解决方案:
https://stackoverflow.com/a/15868352/421195
但你可以通过选角绕过它:
#include <stdint.h> void *ptr1; // Find page start void *ptr2 = (void *) ((uintptr_t) ptr1 & ~(uintptr_t) 0xfff)
至于C++,只需使用relpret_cast,而不用C样式的强制转换。
-
只有当";指针";恰好与";unsigned int";;如果你的特定平台恰好有一个";扁平的";内存模型。
-
Q: 为什么这是一个问题呢?
A: 因为一个";指针";并不总是容易映射到";unsigned int";(或"无符号长")。
示例:16位DOS指针:
- 近指针:用于在16位机器上存储当前段内的16位地址
- 远指针:通常为32位。为了使用它,编译器分配一个段寄存器来存储段地址,然后分配另一个寄存器来存储当前段内的偏移量
- 巨大的指针:通常也是32位,但可以访问外部段
- 你不能只是天真地"旋转钻头";。在远指针的情况下,段是固定的。在远指针中,分段部分不能修改,但在巨大指针中可以修改
";真实模式DOS";只是许多(再次是特定于平台的)例子中的一个;扁平的";内存模型不容易应用。
另请参阅:
- comp.lang.cFAQ列表·问题5.17
我在研究为什么不能在C中对指针进行逐位操作,有办法解决这个问题吗?并注意到,大多数响应都说,由于指针在标准中没有很好地定义,所以对指针的逐位操作没有很好的定义。
这对那个问题的答案描述得很差。他们实际上做说的事情之一是,你不能对指针执行按位操作,因为
- 标准说你不能
- 它不会有用或有意义
- [指针上的按位操作]的语义没有得到很好的定义
- 该标准没有对指针的表示提出要求
从中得到的主要信息是,您不能对指针执行按位操作,因为语言规范没有定义此类操作的含义。为什么会这样?你认为摆弄地址的比特有什么意义?如果有什么不同的话,结果会指向什么?在什么条件下结果必须有效?
然而,这从未出现在我的任何系统类中,我也不知道指针可能是指针指向的内存地址的值。
语言规范用对象地址标识指针值,但语言规范的意思不一定是可以用作需要地址的CPU指令的操作数的对象。有一些C实现中存在这些差异。
你似乎也在假设一个平面地址空间,这样就可以合理地解释一个";地址";作为(单个)数字。过去和现在都有机器体系结构,但事实并非如此。
即使考虑对C指针执行逐位操作,也需要考虑错误的抽象级别。
有没有计划改变这一点,以便在未来的C标准中很好地定义指针?
指针已经根据其预期用途进行了很好的定义。它们不是整数,也不打算被视为整数。这种情况不太可能改变,因为它不会起到有用的作用。他们的陈述不太可能比现在更具体,因为那样会适得其反。
是否有任何C的实现中指针不表示为指针指向的内存地址?
通常,不,这是指针的基本思想。您可以将NULL视为指针的一个示例,我们在逻辑上使用该指针作为非地址。在安全上下文中,指针可以被加密,或者低位被用作动态分析的标签。这里有一个例子。因此,在这些上下文中,指针仍然表示地址,但在静止时可能看起来不像地址。
有没有计划改变这一点,以便在未来的C标准中很好地定义指针?
标准非常清楚指针代表什么。在第6.2.5节中,它将指针描述为以下
指针类型可以从函数类型或对象类型派生,称为引用类型。A.指针类型描述一个对象,该对象的值提供对被引用的实体的引用类型从引用类型T派生的指针类型有时被称为"指针类型";指向T"的指针;。
因此,任何不引用对象的指针的使用都是对标准的滥用。