Калечащее имя в Си

Из моей памяти искаженное имя не используется в C, что является своего рода функцией, которой мы пользуемся, используя функцию C для ABI (Application Binary Interface). Но недавно я читал эту статью о калечащем имени в Си

https://gustedt.wordpress.com/2011/06/24/name-mangling-in-c/

Вопрос здесь в том, будет ли компилятор искажать имя функции C?

1 ответ

Поскольку C - это язык программирования, который не поддерживает перегрузку функции имени, он не изменяет имя. Но для компиляторов, ориентированных на платформу Microsoft Windows Platform, которая имеет множество соглашений о вызовах, таких как _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) */

Имена функций не будут искажены, за исключением, очевидно, в случае идентификаторов Unicode. Например:

// Mangled as "o_u03ba" using Intel's compiler "icc").
extern int o\u03ba(void);

Вопрос с 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);

Поскольку технически вы не можете взять адрес функции и надежно напечатать его, лучшее, что вы можете сделать, - это однозначно определить, какая функция вызывается.

Другие вопросы по тегам