为什么编译器在 static_cast(ing) 一个函数为 void* 时表现不同?
Why do compilers behave differently when static_cast(ing) a function to void*?
以下代码在 VSC++2017 中编译没有任何错误,在 gcc 7.3.0 中无法编译 (error: invalid static_cast from type ‘int(int)’ to type ‘void*’
void* p = static_cast<void*>(func)
)
#include <iostream>
int func(int x) { return 2 * x; }
int main() {
void* p = static_cast<void*>(func);
return 0;
}
函数只能隐式转换为函数指针。 函数指针不是语言中严格意义上的指针,后者仅指指向对象的指针。
无法使用 static_cast
将函数指针转换为 void*
。显示的程序格式错误。如果编译器不发出警告,则说明它不符合标准。编译错误的程序失败并不违反标准。
在保证void*
能够指向函数的系统上(例如POSIX),您可以使用reinterpret_cast
代替:
void* p = reinterpret_cast<void*>(func);
但这对于缺乏保证的系统是不可移植的。 (我知道没有一个系统有 C++ 编译器并且没有这个保证,但这并不意味着这样的系统不存在)。
标准报价:
[expr.reinterpret.cast]
Converting a function pointer to an object pointer type or vice versa is conditionally-supported. The meaning
of such a conversion is implementation-defined, except that if an implementation supports conversions in both
directions, converting a prvalue of one type to the other type and back, possibly with different cv-qualification,
shall yield the original pointer value.
请注意,此条件支持不会扩展到指向成员函数的指针。指向成员函数的指针不是函数指针。
以下代码在 VSC++2017 中编译没有任何错误,在 gcc 7.3.0 中无法编译 (error: invalid static_cast from type ‘int(int)’ to type ‘void*’
void* p = static_cast<void*>(func)
)
#include <iostream>
int func(int x) { return 2 * x; }
int main() {
void* p = static_cast<void*>(func);
return 0;
}
函数只能隐式转换为函数指针。 函数指针不是语言中严格意义上的指针,后者仅指指向对象的指针。
无法使用 static_cast
将函数指针转换为 void*
。显示的程序格式错误。如果编译器不发出警告,则说明它不符合标准。编译错误的程序失败并不违反标准。
在保证void*
能够指向函数的系统上(例如POSIX),您可以使用reinterpret_cast
代替:
void* p = reinterpret_cast<void*>(func);
但这对于缺乏保证的系统是不可移植的。 (我知道没有一个系统有 C++ 编译器并且没有这个保证,但这并不意味着这样的系统不存在)。
标准报价:
[expr.reinterpret.cast]
Converting a function pointer to an object pointer type or vice versa is conditionally-supported. The meaning of such a conversion is implementation-defined, except that if an implementation supports conversions in both directions, converting a prvalue of one type to the other type and back, possibly with different cv-qualification, shall yield the original pointer value.
请注意,此条件支持不会扩展到指向成员函数的指针。指向成员函数的指针不是函数指针。