![](/img/trans.png)
[英]ISO C++ forbids casting between pointer-to-function and pointer-to-object
[英]Casts between pointer-to-function and pointer-to-object in C and C++
我对以下内容有误吗?
C++ 标准说函数指针和对象指针(和返回)之间的转换是条件支持的,实现定义的语义,而所有 C 标准都说这在所有情况下都是非法的,对吧?
void foo() {}
int main(void)
{
void (*fp)() = foo;
void* ptr = (void*)fp;
return 0;
}
ISO/IEC 14882:2011
5.2.10 重新解释转换 [expr.reinterpret.cast]
8 有条件地支持将 function 指针转换为 object 指针类型,反之亦然。 这种转换的含义是实现定义的,除非实现支持双向转换,将一种类型的纯右值转换为另一种类型并返回,可能具有不同的 cvqualification,应产生原始指针值。
我现在在 C 标准中找不到任何关于它的信息......
你是对的,C(99)标准没有说明从指针到函数到指针到对象的转换,因此它是未定义的行为。 *
J.5.7函数指针强制转换
指向对象或void的指针可以转换为指向函数的指针,允许将数据作为函数调用(6.5.4)。
指向函数的指针可以转换为指向对象的指针或void,允许检查或修改函数(例如,通过调试器)(6.5.4)。
在所有C标准中,没有定义指针到函数和指向对象的指针之间的转换,在C ++ 11之前的C ++中,不允许转换,编译器必须给出错误,但有些编译器接受了转换为C和向后兼容性因为对动态加载的库访问(例如dlsym
POSIX函数强制使用它)很有用。 C ++ 11引入了有条件支持的功能的概念,用它来使标准适应现有的实践。 现在,编译器应该拒绝尝试进行此类转换的程序,或者它应该遵守给定的有限约束。
虽然演员的行为不是由标准的“核心”定义的,但在C99基本原理文件(6.3.2.3, 指针 )中明确将此案例描述为无效:
关于函数的指针没有任何说法,这可能与对象指针和/或整数不相称。
即使使用显式强制转换,将函数指针转换为对象指针或指向void的指针也是无效的,反之亦然。
由于它可能有用,它在标准的附件J中也被称为“公共扩展”(C11标准J.5.7, 函数指针转换 ):
指向对象或
void
的指针可以转换为指向函数的指针,允许将数据作为函数调用(6.5.4)。指向函数的指针可以转换为指向对象的指针或
void
,允许检查或修改函数(例如,通过调试器)(6.5.4)。
将其描述为扩展意味着这不是标准要求的一部分(但不需要,任何明确行为的遗漏就足够了)。
POSIX 标准规定:
2.12.3指针类型
所有 function 指针类型应具有与指向 void 的类型指针相同的表示。 将 function 指针转换为 void * 不应改变表示。 可以使用显式转换将由此类转换产生的 void * 值转换回原始 function 指针类型,而不会丢失信息。
注意:ISO C 标准不要求这样做,但符合 POSIX 要求。
这个要求最终意味着任何想要能够支持 POSIX 的 C 或 C++ 编译器都将支持这种类型的转换。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.