C ++编译器经常修改函数名称以支持许多功能。程序员可以使用外部“ C” 方式禁止默认名称处理。但是,为什么int main(int, char **)
从未受到影响?
// test.cpp
int max(int a, int b) {
return a > b ? a : b;
}
extern "C" {
int min(int a, int b) {
return a < b ? a : b;
}
}
int main (int argc, char *argv[]) {
return 0;
}
和
$ xcrun --sdk macosx clang -x c++ -c test.cpp -o test
$ xcrun nm -nm test
0000000000000000 (__TEXT,__text) external __Z3maxii
0000000000000030 (__TEXT,__text) external _min
0000000000000060 (__TEXT,__text) external _main
很显然,int max(int, int)
被改成__Z3maxii
; int min(int int)
无需使用外部“ C” 注释进行修改。
主要如何摆脱混乱?
除了上述注释,还有其他方法可以防止名称混乱吗?
答案 0 :(得分:7)
每[basic.start.main]/1
,[basic.start.main]/2
和[over]/1
:
程序应包含一个名为
main
的全局函数。 [...]此功能不得重载。 [...]当在同一范围内为单个名称指定两个或多个不同的声明时,该名称被称为重载 [...]。
这是未定义的行为,以便在全局名称空间中具有名称main
的任何内容。这样一来,就没有理由修改main
甚至认为它是适当的功能。
答案 1 :(得分:5)
名称修饰是C ++编译器用来为程序中的每个函数赋予唯一名称的过程。在C ++中,程序通常至少有几个具有相同名称的函数,即函数重载,但是Main是特殊的,它实际上是C语言的全局函数,永远不能被重载,因此没有必要。
看看https://en.cppreference.com/w/cpp/language/main_function
还有questions about name mangling in C++
(主要)特殊属性
它不能预定义也不能重载:实际上,全局名称空间中的main名称是为函数保留的(尽管它可以用于命名类,名称空间,枚举以及非全局名称空间中的任何实体,但不能在任何名称空间中使用C语言链接声明一个名为“ main”的函数(自C ++ 17起)