gpt4 book ai didi

c++ - 将函数地址转换为 64 位整数 : Undefined/Ill-behaved?

转载 作者:太空宇宙 更新时间:2023-11-04 08:35:37 26 4
gpt4 key购买 nike

背景:我有一个场景,我必须允许比较两个仿函数对象,使用唯一 ID 来测试它们是否相等(我不能简单地检查它们的地址是否相同,因为函数指针本身不存储在对象中)。最初,我有这个想法,简单地从 0 开始 id 生成器并无限递增:

struct GenerateUniqueID{
static std::size_t id_count = 0;

auto operator()() -> std::size_t { return (id_count++); }
};

...但是,由于我每隔几秒就创建了成千上万个这样的对象,我实际上设法遇到了 id_count 溢出回 0 的情况!结果……令人不快。现在,我的第二个想法是,由于这些仿函数显然是函数的包装器,我可以通过将函数指针的地址转换为 64 位整数并将其存储在类中进行比较来执行比较.见:

//psuedocode
struct Functor{
std::uint64_t id;

auto generate_id_from_function_address(function f) -> void {
id = reinterpret_cast<std::uint64_t>(&f);
}
};

现在,我的担心很简单:将函数指针强制转换为 64 位整数是否行为不当/未定义?在 32 位架构上?在 64 位架构上?在两者上?我在这里主要关心的是虚函数,因为我知道对于内联函数,编译器只是创建一个非内联版本,所以那里没有问题。

最佳答案

将常规指针(更不用说函数指针)转换为 uint64_t 是实现定义的,因为指针可能比 64 位宽。如果您使用 uintptr_t(并且该类型存在),则转换定义明确。

将函数指针转换为任何整数类型是实现定义的(即使您使用 uintptr_t),因为函数指针可能比常规指针更宽。 POSIX 等其他一些标准明确允许这样做,因此在 POSIX 下,将函数指针转换为数据指针(如 void*uintptr_t)是安全的。

(将指向成员的指针转换为整数、数据指针或常规函数指针是未定义的,并且在实践中可能总是会失败,因为它们比常规指针大。)

但是,使用 uint64_t 而不是 size_t 作为您的唯一 ID 可能更简单。由于 uint64_t 的范围很大,因此基本上不可能通过重复递增来溢出它。

关于c++ - 将函数地址转换为 64 位整数 : Undefined/Ill-behaved?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26352358/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com