常用的几类函数
#include <iostream>
void func(int a){
std::cout << "global func: " << a << std::endl;
}
namespace test{
void func(int a){
std::cout << "namespace test func: " << a << std::endl;
}
};
class Demo {
public:
void func(int a){
i = 1;
std::cout << "class member func: " << a << std::endl;
}
int i{
0};
};
int main()
{
func(1);
test::func(1);
Demo d;
d.func(1);
return 0;
}
函数的重载
对于程序的整个生命周期如下:编写程序(源代码)-> 预处理 -> 编译(扫描->词法分析->语法分析->语义分析->源代码优化->代码生成->目标代码优化) -> 汇编 -> 链接 -> 运行;
编译器将源代码编译产生目标文件时,符号名与相应的变量和函数进行对应,在比较早的时候,两者是一样的,比如汇编源代码中包含一个函数foo,编译成目标文件时,对应的符号名也是foo;C语言的规则比较类似,将全局变量和函数的符号名前加上下划线"_";
比如:
extern "C" {
void func(int a){
std::cout << "global func: " << a << std::endl;
}
}
编译成的符号如下(readelf -s main | grep func):
Num: Value Size Type Bind Vis Ndx Name
60: 00000000000011e9 74 FUNC GLOBAL DEFAULT 16 func
由于C语言的符号生成规则如此,所以不支持函数的重载。也因此只要符号相同(相同的函数名、变量名会编译失败)
那么对于C++,它拥有类、继承、虚机制、重载、名称空间等这些特性,使符号管理(符号生成规则)更为复杂。为了支持这些特性,发明了Name Decoration 或 Name Mangling机制
看如下函数的符号是如何:
int func(int){
return 0;};
float func(float){
return 0;