【问题标题】:is it possible to convert a function pointer to an integer?是否可以将函数指针转换为整数?
【发布时间】:2015-11-07 20:33:00
【问题描述】:

我想以明确的方式做这样的事情:

struct S
{
  static some_integral_type f() noexcept
  {
    return some_cast<...>(&f);
  }
};

整数可以有符号或无符号。结果应该与指向uintptr_tintptr_t 的对象指针的转换相同。对于函数指针,不能保证对这些进行 AFAIK 强制转换。就我所知,即使转换为 uintmax_tintmax_t 也可能不起作用。

我需要这个,所以我可以从函数指针生成一个唯一的“句柄”,然后我可以在 switch 语句中使用它。

【问题讨论】:

  • 结果整数应该是什么?内存地址?
  • 听起来像是 XY 问题。想要真正实现什么?
  • 如果你真的必须这样做,至少使用(u)intptr_t以避免任何数据丢失。
  • @zenith 是的,但是函数和成员函数指针不是对象指针。
  • 那个答案是错误的和无关紧要的。

标签: c++ c++14


【解决方案1】:

一般来说不会。

首先,成员函数指针(和成员指针)是标准中很少提及非常的毛茸茸的野兽。
所以,让我们暂时忽略它们。

接下来,甚至可能无法通过void* 往返普通旧函数指针,并且标准仅定义了一种用于通过整数往返数据指针的类型,如果实现支持这样的话:
(u)intptr_t.

当然,如果您的实现具有足够大的整数类型,您可以手动执行此操作,方法是将指针读取为 unsigned char[] 并将其组合为单个数值,然后该操作是可逆的。

请注意,如果你走这条路,相同的函数指针可能会导致不同的数字,因为同一个指针可以有多种可能的表示形式(例如填充字节、非值位、分段)......

【讨论】:

  • 请注意,如果你走这条路,相同的函数指针可能会导致不同的数字......为什么?
  • @user1095108:好吧,让我们以x86,分段内存为例:可以有多种方法来引用相同的函数,不同的段偏移量对。此外,其中可能有填充(32bit-offset,16bit-segment,2 Byte padding)。
  • 在 POSIX 兼容的系统上,您保证能够将函数指针转换为 void 指针;反之亦然
  • @Deduplicator 请检查我的非标准解决方案。
【解决方案2】:

您可以尝试使用元函数选择与函数指针大小相同的整数 - 所需大小为sizeof(void(*)())。但是,不能保证存在任何此类整数类型。

实际上,将其转换为 void* 或 intptr_t 几乎适用于所有主流平台。

【讨论】:

  • 那我可以试试intmax_tuintmax_t。如果这些都不起作用,那么什么都不会。
  • @user1095108:实际上,一些编译器支持大于intmax_t 的整数,因为由于 ABI 兼容性,它们无法更改后者。
  • @Deduplicator 那么unsigned long longlong long 怎么样?
【解决方案3】:

取自Can std::hash be used to hash function pointers?

在之前的尝试中,我尝试将函数指针转换为 void*,这是不允许的,也不能编译(参见: https://isocpp.org/wiki/faq/pointers-to-members#cant-cvt-memfnptr-to-voidptr 详情)。原因是 void* 是数据指针,而 函数指针是代码指针。

【讨论】:

  • 我不是在寻找哈希,因为它们可能会发生冲突。也就是说,2 个不同的函数指针可能会产生相同的哈希值。
  • 既然您可以使用成员函数指针进行相等性检查,那应该不是问题。请参阅stackoverflow.com/questions/1328238/… 了解更多信息。
猜你喜欢
  • 2020-11-22
  • 1970-01-01
  • 2015-11-08
  • 1970-01-01
  • 1970-01-01
  • 2013-03-17
  • 1970-01-01
  • 2012-01-27
  • 2021-02-13
相关资源
最近更新 更多