只有 C++ 支持函数重载,C 语言不支持函数重载。
从语言特性和编译器实现两个层面来解释:
1. 语言层面的规定
-
C 语言:不允许在同一作用域内定义同名函数。如果出现两个同名函数,编译器会直接报"重复定义"错误。
-
C++:允许在同一作用域内定义多个同名函数,只要它们的参数列表不同(参数个数、类型或顺序不同)。注意:仅返回值类型不同不构成重载。
cpp
// C++ 合法
int add(int a, int b);
double add(double a, double b);
cpp
// C 非法,编译报错
int add(int a, int b);
double add(double a, double b);
2. 底层原因:名字修饰(Name Mangling)
C 和 C++ 编译后,函数名在符号表中的处理方式不同:
-
C 语言:函数名在符号表中基本就是原名字,如 `add`。如果有两个 `add`,链接时符号冲突,无法区分。
-
C++:编译器会把函数名和参数类型一起编码成唯一的符号名(名字修饰)。例如:
-
`add(int, int)` → `_Z3addii`
-
`add(double, double)` → `_Z3adddd`
因为符号名不同,链接器能够区分它们,所以重载得以实现。
3. 补充:`extern "C"`
在 C++ 中,如果希望某个函数按 C 的方式编译(不进行名字修饰),可以用 `extern "C"` 声明:
cpp
extern "C" int add(int a, int b);
被 `extern "C"` 修饰的函数 不能重载,因为它的符号名不再包含参数信息。这也是 C++ 调用 C 库函数时需要加 `extern "C"` 的原因。
