64位linux上的函数指针大小

Function pointer size on 64 bit linux

本文关键字:指针 函数 linux 64位      更新时间:2023-10-16

我正在编写一个更简单(更快)的std/boost::函数。我主要关心的是简单性和效率,平台被限制为x86-64 linux,使用gcc和clang编译。

在上述限制下,是否可以假设

  1. 所有函数指针,即指向自由函数的指针、成员函数(POD的、带有虚方法的类、派生类、虚继承类……)、函子、lambda…所有的大小都不超过16字节吗?
  2. 对齐要求是什么?

对于x86_64,可以放心地假设任何指向函数和/或成员的指针都不会超过指向成员函数的指针的大小。对于GCC,这将是sizeof(void*),对于clang,这将是sizeof(void*)*2(上次我检查过)。对齐要求是16字节。使用GCC,您可以依赖__BIGGEST_ALIGNMENT__预定义宏。然而,它在clang上是缺席的。我唯一能建议的是尽量不要假设,而是使用计算最大大小的编译时表达式。

更新:

正如@David所指出的,在多重继承和/或虚拟继承的情况下,8字节可能不足以分派成员函数调用。因此,sizeof(void*)*2在两种情况下都适用,以保持安全。

最好的方法仍然是使用sizeof的编译时表达式。例如:

struct Foo {
};
typedef void* (Foo::*pmf)();
typedef void* (*bar)();
constexpr auto max_func_pointer_size() -> decltype(sizeof(void*)) {
    return sizeof(pmf) > sizeof(bar) ? sizeof(pmf) : sizeof(bar);
}
int main()
{
    static_assert(max_func_pointer_size() == 16, "oops!?");
}