函数指针的大小有啥保证?
Posted
技术标签:
【中文标题】函数指针的大小有啥保证?【英文标题】:What is guaranteed about the size of a function pointer?函数指针的大小有什么保证? 【发布时间】:2011-04-25 21:39:12 【问题描述】:在 C 中,我需要知道结构的大小,其中包含函数指针。我可以保证在所有平台和架构上:
void* 的大小与函数指针的大小相同? 函数指针的大小不会因其返回类型而有所不同? 函数指针的大小不会因其参数类型而有所不同?我认为所有这些的答案都是肯定的,但我想确定一下。就上下文而言,我打电话给sizeof(struct mystruct)
,仅此而已。
【问题讨论】:
【参考方案1】:来自 C99 规范,第 6.2.5 节,第 27 段:
指向 void 的指针应具有相同的 表示和对齐 需求作为一个指针 字符类型。同样,指针 到合格或不合格的版本 兼容类型应具有相同的 表示和对齐 要求。所有指向的指针 结构类型应具有相同的 表示和对齐 互相要求。全部 指向联合类型的指针应具有 相同的表示和对齐 互相要求。指针 其他类型不必有相同的 表示或对齐 要求。
所以不;不保证void *
可以保存函数指针。
以及第 6.3.2.3 节第 8 段:
指向一种类型的函数的指针 可以转换为指向 a 的指针 另一种类型的功能并返回 再次;结果应比较相等 到原来的指针。
暗示一种函数指针类型可以保存任何其他函数指针值。从技术上讲,这与保证函数指针类型不能改变大小不同,只是保证它们的值彼此占据相同的范围。
【讨论】:
【参考方案2】:不,不,不。
C 不支持具有不同代码和数据指针大小的哈佛架构,因为理想情况下,在为此类架构编程时,您希望将数据存储在程序内存中(字符串文字等),并且您需要这样做对象指针指向代码空间。但它并没有禁止它们,所以就标准而言,函数指针可以引用与数据地址空间大小不同的地址空间。
但是,任何函数指针都可以转换为另一个函数指针类型[*]并返回而不会丢弃值,就像任何对象指针都可以转换为void*
并返回一样。因此,函数指针的大小会根据其签名而变化,这将是相当令人惊讶的。如果您必须能够以某种方式在更小的空间中存储相同的值,然后在回退时检索它,那么额外的空间没有明显的“用途”。
[*] 谢谢,肖特。
【讨论】:
更一般地说:任何函数指针都可以转换为任何其他函数指针类型并返回。 (C99 6.3.2.3/8) @schot:对,在那种情况下,让它们不同大小确实是不正当的,因为无论大小如何,所有函数指针类型都必须表示完全相同的一组值。即每个函数的地址,加上一个空指针。 优秀的答案。我前几天的问题在这里说明了潜在的陷阱:***.com/questions/3889541/… "C 并不真正支持哈佛架构";我认为这是一个红鲱鱼。有很多这样的架构支持 C! @Oli:当然,您可以将内容复制到数据空间中,但是您有(a)但没有(b)。您正在占用宝贵的内存,这正是程序员控制优化的动机。通过“丑陋的黑客”,我想到了nongnu.org/avr-libc/user-manual/pgmspace.html。然后你不能得到一个真正的“对象”指针,例如程序本身可以传递给memcpy
,因为 memcpy 不知道如何取消引用它。要做到这一点,你必须投降,只是增加对象指针的大小,再次消耗宝贵的内存,并且可能需要在每次内存访问时进行运行时切换!【参考方案3】:
除了其他答案,***这样说:
http://en.wikipedia.org/wiki/Function_pointer
虽然 C 中的函数指针和 C++ 可以很简单地实现 地址,所以通常
sizeof(Fx)==sizeof(void *)
,会员 C++中的指针经常被实现 作为“胖指针”,通常是两个或 一个简单的大小的三倍 函数指针,为了处理 使用虚拟继承。
函数指针是一种抽象。只要满足标准的要求,一切皆有可能。 IE。如果您的程序中的函数少于 256 个,则函数指针可以通过使用单个字节来实现,其值为 0 表示 NULL,值 1 到 255 作为具有物理地址的表的索引。如果超过 255 个函数,可以扩展为使用 2 个字节。
【讨论】:
我不明白这是怎么回事。对于合法的 C 实现来说,这确实是一种可能性,但如果有这样的实现,我会感到惊讶。 不是我的反对意见,但是 C++ 成员指针的东西是无关紧要的,因为问题是关于 C 的。最后一段是一个非常好的观点,不过,函数指针当然 可以 合法地成为某个表的索引,具有额外的间接级别来实际调用它们。【参考方案4】:有一个过去很常见的不同尺寸的实际示例。在 MS-DOS 和早期的 Windows C 编程中,在“中等”内存模型中,您有 16 位数据指针和 32 位函数指针,而“紧凑”内存模型则相反。
【讨论】:
以上是关于函数指针的大小有啥保证?的主要内容,如果未能解决你的问题,请参考以下文章
为啥free函数不在释放内存后,将指针置NULL,野指针有啥用