指针的大小是多少? 它究竟依赖于什么?
我在网上搜索,虽然我可以找到一些讨论,但我没有找到全面的描述。 因此,如果任何人都可以形成一个涵盖指针大小的答案,那将会有很大的帮助。 答案至少应包括以下主题
- 指针的大小取决于什么?
- 架构的哪些特性会影响指针的大小? (详细地)
- 编译器如何影响指针的大小?
指针是由高级语言提供的抽象; 理论上它可以是任何宽度。 这完全是编译器的奇思妙想。
实际上,它通常与底层硬件的内存地址的宽度有关,因为这通常是编译器实现的最有效的方法。 但也有例外; 例如,C ++的指向成员函数的指针没有直接映射到硬件地址,因为它需要代表两个实体(函数和类型的一些概念)。
然而,即使把它放在一边,仍然存在复杂性。 例如:
- 在大多数现代硬件上,您的程序将使用虚拟内存地址,而不是物理地址(可能不是相同的宽度)。 除非您正在编写内核空间代码。
- 在某些体系结构(例如x86)上,底层硬件展示了分段地址空间。 这非常复杂,但主要是由操作系统和虚拟内存系统抽象出来的。 如果您正在为真正的旧x86编写内核空间代码或代码,那么您将不得不处理它。
- 在当前的x86-64上,(虚拟)内存地址实际上只有48位宽。
- x86-64支持32位和64位可执行文件。
- 您可能正在虚拟机内运行,如果需要,它也可以执行任何操作(相对于底层物理机)。
这个问题最初标记为C和C ++,而不是“语言不可知”。 作为一个与语言无关的问题,它应该被视为过于宽泛 ,但我希望OP将其恢复为原始版本1,因此我不会投票结束。 作为一个C / C ++问题,虽然显然是负责任的,但它被视为过于宽泛,然后当范围被极大地扩展到无法回答时,通过将该标记更改为与语言无关,它被重新打开为现在可以回答。
我正在回答C ++的原始问题,这里和那里散布着一些C知识。
我认为目前的“语言不可知”问题是无法回答的,尽管有一种尝试与语言无关的答案。
1.指针的大小取决于什么?
普通数据指针所需的最小尺寸取决于指向类型或不同function的对象的可能存储位置的最大数量; 为了区分n个可能的位置,需要ceil(lg2( n ))位。
因此,最小指针大小取决于最大可能的内存大小。
因此,最小指针大小也取决于指向类型的对齐。 在一些现在过时的机器上,甚至可能在一些现存的机器(大型机?)上,硬件级别可寻址的存储器单元是例如2或4个字节的字。 然后可以使用小指针来寻址字对齐的数据,而char*
因此也需要更大的void*
。
因此,§3.9.2/ 4中的C ++ 11标准要求“类型为cv void*
的对象应具有与cv char*
相同的表示和对齐要求。”
C ++中的成员函数指针更类似于偏移而不是指针,并且通常比正确的指针更大。
2.架构的哪些特性会影响指针的大小? (详细地)
从C ++可以看出主要是可记录的内存范围。
但值得回顾的是,在MS-DOS编程中,一个区别在近指针和远指针之间。 近指针是一个隐含的64K内存段的偏移量,而一个两倍大小的远指针组合了一个段选择器和偏移量。
在(仍然)现代32位PC编程C和C ++指针通常类似于近指针,不支持远指针,这将是6个字节。 要使用这样的指针,必须使用汇编语言等其他语言。
3.编译器是否会影响指针的大小? 怎么样?
所使用的编译器和编译选项原则上可以影响指针大小,因为标准没有规定大小。 例如,它原则上可以添加信息以帮助调试。 或者如上所述,使用语言扩展可以有近距离和远距离指针。
由于成员指针不是直接地址(在引擎盖下),因此编译器如何表示它们以及它们有多大。
这也取决于使用的选项。
4.什么是不同类型的指针以及它们彼此之间有何不同? (例如:函数指针和指向基本数据类型的指针之间是否存在差异?,指针与远指针之间等)
在C ++ 03中,函数指针无法转换为数据指针,反之亦然。 这种限制支持具有哈佛架构的机器,并且它支持可能的不同大小的函数指针和数据指针(例如,前者为远 ,后者为近 )。 在C ++ 11中, 有条件地支持这种转换,在§5.2.10/ 8中,由缺陷报告195产生 。
值得注意的是,Posix标准需要支持转换(函数指针)→( void*
)和返回,例如对于dlsym
函数。
上述有效意味着对象指针和函数指针是不同的。 例如,后者不支持地址算术。 此外,成员指针与正确的指针不同,更类似于偏移。
Modern C ++不支持near指针和远指针。
5.语言是否对指针有影响。 C vs C ++
C不支持成员指针,只要它们被认为是这个问题的指针。
除此之外,C ++的主要目标是能够直接使用C库,并将C标准“合并”(C ++11§17.5.1.5/ 1)到C ++标准中,这需要兼容的指针表示。
C支持限制指针,限定符restrict
,C ++不支持。 但是,这只会影响编译器对指针可能值的了解。 这意味着C编译器可能能够发出更好的优化代码。