最近在看 C++ 的方法重载,我就在想 C# 中的重载底层是怎么玩的,很多朋友应该知道 C 是不支持重载的,比如下面的代码就会报错。
#include
int say() {
return 1;
}
int say(int i) {
return i;
}
int main()
{
say(10);
return 0;
}
从错误信息看,它说 say
方法已经存在了,尴尬。。。
一:为什么 C 不支持
要想寻找答案,需要了解一点点底层知识,那就是编译器在编译 C 方法时会将 函数名
作为符号添加到 符号表
中,这个 符号表
就是 call 到 say方法字节码
中间的一个载体,画个图大概就是这样。
简而言之,call 先跳转到 符号表
, 然后再 jmp 到 say 方法,问题就出现在这里, 符号表是一种类字典结构,是不可以出现 符号
相同的情况。对了,在 windbg 中我们可以用 x
命令去搜索这些符号,
为了论证我的说法,可以在汇编层面给大家验证下,修改代码如下:
#include
int say(int i) {
return i;
}
int main()
{
say(10);
return 0;
}
接下来再看下汇编。
00C412AD jmp say (0C417B0h)
003B2E5F push 0Ah
003B2E61 lea ecx,[person]
003B2E64 call Person::sayhello (03B13A2h)
00007FFB82134E07 mov rcx,qword ptr [1A8C65E8h]
00007FFB82134E0F call Method stub for: ConsoleApp1.Program.Say(System.String) (07FFB81F6F120h)
00007FFB82134E14 nop
从输出信息看,同样也是两个符号表地址,然后由符号表地址 jmp 到最后的方法体。
`c#
00007FFB81F6F118 jmp ConsoleApp1.Program.Say(Int32) (07FFB82134F10h)
Original: https://www.cnblogs.com/huangxincheng/p/16378081.html
Author: 一线码农
Title: 聊聊 C# 方法重载的底层玩法
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/549262/
转载文章受原作者版权保护。转载请注明原作者出处!