从我的记忆中,在C中没有使用修改名称,这是我们利用C函数用于ABI(应用程序二进制接口)的一种功能。但最近我一直在阅读这篇关于在C
中修改名称的文章https://gustedt.wordpress.com/2011/06/24/name-mangling-in-c/
这里的问题是,如果在任何情况下编译器都会破坏C函数名?
答案 0 :(得分:0)
除了Unicode标识符外,功能名称不会被破坏。例如:
icc
当编译器生成非唯一符号名称时,问题中链接的博客文章突出显示//Both will have the same symbol name.
extern void o\u03ba(volatile int *p)
{
*p = -32767;
}
extern void o_u03ba(volatile int *p)
{
*p = 0;
}
...
volatile int n;
// Should print -32767; may print 0 or -32767.
o\u03ba(&n);
printf("%d\n", n);
// Should print 0; will print the same thing as the previous line.
o_u03ba(&n);
printf("%d\n", n);
的问题显然是一个问题:
static
使用static void foo\u03ba(volatile int n)
{
printf("foo\\u03ba: n = %d\n", n);
}
static void foo_u03ba(volatile int n)
{
printf("foo_u03ba: n = %d\n", n);
}
...
volatile int n = 10;
// These two lines may print the same thing.
foo\u03ba(n);
foo_u03ba(n);
关键字声明的函数具有内部链接。尽管如此,编译器的内部表示仍然可能使用一个受损的名称,尽管您在结果程序中永远不会看到它。但是,在解析对函数的引用时,文章提供的代码表明即使使用该名称也会导致问题:
{
"workshops":[
{
"workshop1":{
"id":1
}
},
{
"workshop2":{
"id":2
}
},
{
"workshop3":{
"id":3
}
},
{
"workshop4":{
"id":4
}
}
]
}
由于您在技术上无法获取函数的地址并可靠地打印它,因此您可以做的最好的事情就是唯一地识别调用哪个函数。
答案 1 :(得分:0)
由于C是不支持名称函数重载的编程语言,因此它不进行名称修饰。但是对于针对Microsoft Windows平台的编译器而言,该平台具有_cdecl,_stdcall等各种调用约定。这些函数名称经过修饰以提供有关调用约定的信息。
例如,
int _stdcall fun(int myVar) {return 0;}
int _fastcall fun(int myVar){return 1;}
int _cdecl fun(int myVar){return 2;}
编译器(32位)的输出将如下所示:
_fun@4 /* _(function_name)@(argument_size_in_bytes) */
@fun@4 /* @(function_name)@(argument_size_in_bytes) */
_fun /* _(function_name) */