【问题标题】:Integer type for holding function pointers?用于保存函数指针的整数类型?
【发布时间】:2020-11-18 14:12:47
【问题描述】:

我应该使用什么标准定义的整数类型来保存指向函数的指针?是否有类似(void*) 的函数类型可以容纳任何函数?

很确定它不是[u]intptr_t,因为标准明确表示它是用于指向对象的指针,并且标准明确区分了指向对象的指针和指向函数的指针。

【问题讨论】:

  • 我相信可以保证在任何类型的函数指针之间进行转换是安全的,因此您可以使用void (*)() 作为void * 的替代品。我不知道整数类型。
  • @NateEldredge 它不完全符合标准。该类型是没有原型的函数类型,在“未来语言方向”中,标准说:“使用没有原型的函数声明符是一个过时的特性”
  • "Obsolecent" 现在仍然很流行,对吧?如果您愿意,请使用void (*)(void)

标签: c pointers integer language-lawyer


【解决方案1】:

整数类型没有指定的类型足以编码函数指针。

替代方案:

  • 更改代码以取消对该整数类型的需求。很少真正需要这种整数类型。

  • union 中使用数组:unsigned char[sizeof( int (*)(int)) )]int (*f)(int)) 以允许对指针的整数性进行一些检查。仍然可能存在填充问题。归结为代码想要对这样一个整数做什么。

  • 使用uintmax_t 并且希望就足够了。 _Static_assert(sizeof (uintmax_t) >= sizeof (int (*)(int)) ); 是一种合理的预防措施,但不能保证成功。


限制规格

任何指针类型都可以转换为整数类型。除非前面指定,结果是实现定义的。如果结果不能以整数类型表示,则行为未定义。结果不必在任何整数类型的值范围内。 C17dr § 6.3.2.3 6


注意,即使 [u]intptr_t 对象指针类型也是一种保证,因为它们是可选类型。

【讨论】:

  • intmax 部分和我想的一样。如果标准委员会看到这一点,希望他们会修改标准,我希望将来会有更新的答案。
  • 我严重反对“使用数组”部分。就是用公牛屠刀杀鸡。
  • @DannyNiu 考虑所有函数指针都是 128 位且最大整数类型为 64 的平台。但这引出了一个问题,你打算如何处理转换为整数的函数指针?跨度>
  • 嗯,我正在试验基于宏和函数的元对象,它返回有关散列函数的信息,例如它的块/输出大小、初始化/更新/最终函数。这些信息混合在一起,因此需要。
  • @DannyNiu 使用unionunsigned char 数组/函数指针是打印函数指针值的兼容可移植方式。该输出的解释是实现定义的,但代码是抱怨的。我不知道打印函数指针的其他抱怨方式 - 实际上是内存转储。
【解决方案2】:

很确定不是[u]intptr_t

这是真的。但区别是为了保证某些基本转换的正确性。如果您查看“The C Programming Language”的第 2 版,那么区别比标准中的当前措辞更容易注意到。

如果您以操作系统为目标平台,那么[u]intptr_t 可能正是您想要的,如:

  1. POSIX 指定返回void *dlsym 函数,要求结果可以转换为函数指针并可用。

  2. Win32 GetProcAddress 的定义方式是,如果返回值不是 NULL,它将是对函数和/或对象有效的有效内存地址。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-10
    • 2014-02-06
    • 2015-01-05
    • 1970-01-01
    • 2015-09-04
    • 2014-07-22
    • 2022-07-10
    • 1970-01-01
    相关资源
    最近更新 更多