当初看到Visual Studio 2010的这个提示,我真当VS实现了C LANG的函数重载。
今天即兴尝试VS下C LANG的函数重载,虽然IDE没报语法错误,但编译器编译时会报错。无奈之下只好打开长长的math.h一探究竟。
通过全文搜索很容易找到math.h声明的pow()原型:
1 2 3 4 5 6 7 8 9 10 11 |
double __cdecl pow(_In_ double _X, _In_ double _Y); inline double __CRTDECL pow(_In_ double _X, _In_ int _Y) {return (_Pow_int(_X, _Y)); } inline float __CRTDECL pow(_In_ float _X, _In_ float _Y) {return (powf(_X, _Y)); } inline float __CRTDECL pow(_In_ float _X, _In_ int _Y) {return (_Pow_int(_X, _Y)); } inline long double __CRTDECL pow(_In_ long double _X, _In_ long double _Y) {return (powl(_X, _Y)); } inline long double __CRTDECL pow(_In_ long double _X, _In_ int _Y) {return (_Pow_int(_X, _Y)); } |
声明的这些原型一眼看上去没什么问题,挺正常的重载方式。不过math.h内容有点多,不细心点还是看不出来,实际上pow()的重载使用了条件编译:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
... #ifdef __cplusplus extern "C" { #endif ... double __cdecl pow(_In_ double _X, _In_ double _Y); ... #ifdef __cplusplus } extern "C++" { ... inline double __CRTDECL pow(_In_ double _X, _In_ int _Y) {return (_Pow_int(_X, _Y)); } inline float __CRTDECL pow(_In_ float _X, _In_ float _Y) {return (powf(_X, _Y)); } inline float __CRTDECL pow(_In_ float _X, _In_ int _Y) {return (_Pow_int(_X, _Y)); } inline long double __CRTDECL pow(_In_ long double _X, _In_ long double _Y) {return (powl(_X, _Y)); } inline long double __CRTDECL pow(_In_ long double _X, _In_ int _Y) {return (_Pow_int(_X, _Y)); } ... } #endif |
查找了一下资料,得知”__cplusplus”是CPP下才有的预定义宏,毕竟”C Plus Plus”……
也就是说,编译C LANG的情况下,仅有这个原型起作用:
1 |
double __cdecl pow(_In_ double _X, _In_ double _Y); |
其他的重载用的原型根本就不会被编译。
这下结论明确,C LANG根本没有函数重载,那就更加别谈对pow()的重载了,只是IDE对条件编译的检测不完善,才有本文首图的那种提示。
最后自己弄一个伪函数重载玩玩:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
#include <stdio.h> #ifdef __cplusplus extern "C" { #endif float fun(double n1, double n2) { return (float) (n1 + n2); } #ifdef __cplusplus } extern "C++" { int fun(float n1, int n2) { return (int) (n1 + n2); } double fun(double n1, int n2) { return n1 + n2; } } #endif int main(int argc, char **argv) { printf("%lf\n", fun(1, 2)); return 0; } |