为什么函数指针参数不影响内存大小?
Why don't function pointer arguments affect memory size?
最近在看gl3w库的src代码。我注意到它为我使用了一种新型结构:a union
。我发现 union
是多种数据类型存在于同一个地方的一种方式。但是我注意到它在类型之间切换而没有重新分配值。它从一个纯 c 函数指针数组和一个具有不同数量参数的函数指针结构切换。所以我做了一些测试:
#include <iostream>
typedef void (*PUREPROC)();
typedef void (*ARGSPROC)(int, int *);
int main() {
std::cout << "PUREPROC's size is: " << sizeof(PUREPROC) << std::endl;
std::cout << "ARGSPROC's size is: " << sizeof(ARGSPROC) << std::endl;
return 0;
}
令我惊讶的是,两者都使用了 8 字节的内存。我了解 gl3w 如何能够在数组和结构之间切换,它们使用相同数量的内存。数组只是一个工具,允许以更简单的方式分配函数。我知道代码有效,也知道它们不会消耗不同数量的内存,但我不知道为什么。这就是我的问题:为什么函数指针参数不影响内存大小?
函数指针仍然只是一个指针,即它包含一个内存地址。
它不包含任何关于指针指向的内容。那是语言的一部分,而不是指针的表示。
这是因为它与任何指针一样只是一个指针,但指向具有特定签名的函数,以便编译器可以推断出如何在调用站点中进行调用。指针通常是一个数字,其中包含它指向的对象的地址,它(指针)的大小与程序编译的 cpu arch 的大小相同。所以 x64 指针是 8 字节 = 64 位,x32 指针是 4 字节 = 32 位等等
指向不同类型的指针可能具有不同的大小,并且指向不带参数的函数的指针可能具有与指向带有一些参数的函数的指针(我无法想象为什么会这样,但这是可能的)。它们也可以具有 相同 大小和对齐方式。
他们是否这样做完全取决于具体实施。在具有“平面”内存模型的系统上(例如,现代 Windows、MacOS 和 x86 和 x86-64 上的 Linux),所有对象指针和函数指针类型的大小往往相同。在像 DOS 这样的分段系统上,您有 near
(16 位)和 far
(32 位)指针,具体取决于您是否引用同一内存段中的某些内容。哈佛架构将代码和数据保存在具有不同地址总线大小的物理独立内存中,因此指向函数的指针可能与指向对象的指针具有不同的大小。
在 C++ 中,唯一的要求(AFAICT,无论如何)是指向限定类型的指针与指向其非限定等价物的指针具有相同的大小和对齐方式,并且 void *
和 char *
具有相同的大小和对齐方式大小和对齐方式。
如果两个不同的指针类型具有相同的大小,您永远不会感到惊讶。如果两个不同的指针类型具有不同的大小(模以上要求),您永远不会感到惊讶。
最近在看gl3w库的src代码。我注意到它为我使用了一种新型结构:a union
。我发现 union
是多种数据类型存在于同一个地方的一种方式。但是我注意到它在类型之间切换而没有重新分配值。它从一个纯 c 函数指针数组和一个具有不同数量参数的函数指针结构切换。所以我做了一些测试:
#include <iostream>
typedef void (*PUREPROC)();
typedef void (*ARGSPROC)(int, int *);
int main() {
std::cout << "PUREPROC's size is: " << sizeof(PUREPROC) << std::endl;
std::cout << "ARGSPROC's size is: " << sizeof(ARGSPROC) << std::endl;
return 0;
}
令我惊讶的是,两者都使用了 8 字节的内存。我了解 gl3w 如何能够在数组和结构之间切换,它们使用相同数量的内存。数组只是一个工具,允许以更简单的方式分配函数。我知道代码有效,也知道它们不会消耗不同数量的内存,但我不知道为什么。这就是我的问题:为什么函数指针参数不影响内存大小?
函数指针仍然只是一个指针,即它包含一个内存地址。
它不包含任何关于指针指向的内容。那是语言的一部分,而不是指针的表示。
这是因为它与任何指针一样只是一个指针,但指向具有特定签名的函数,以便编译器可以推断出如何在调用站点中进行调用。指针通常是一个数字,其中包含它指向的对象的地址,它(指针)的大小与程序编译的 cpu arch 的大小相同。所以 x64 指针是 8 字节 = 64 位,x32 指针是 4 字节 = 32 位等等
指向不同类型的指针可能具有不同的大小,并且指向不带参数的函数的指针可能具有与指向带有一些参数的函数的指针(我无法想象为什么会这样,但这是可能的)。它们也可以具有 相同 大小和对齐方式。
他们是否这样做完全取决于具体实施。在具有“平面”内存模型的系统上(例如,现代 Windows、MacOS 和 x86 和 x86-64 上的 Linux),所有对象指针和函数指针类型的大小往往相同。在像 DOS 这样的分段系统上,您有 near
(16 位)和 far
(32 位)指针,具体取决于您是否引用同一内存段中的某些内容。哈佛架构将代码和数据保存在具有不同地址总线大小的物理独立内存中,因此指向函数的指针可能与指向对象的指针具有不同的大小。
在 C++ 中,唯一的要求(AFAICT,无论如何)是指向限定类型的指针与指向其非限定等价物的指针具有相同的大小和对齐方式,并且 void *
和 char *
具有相同的大小和对齐方式大小和对齐方式。
如果两个不同的指针类型具有相同的大小,您永远不会感到惊讶。如果两个不同的指针类型具有不同的大小(模以上要求),您永远不会感到惊讶。