Рубрики

Название Mangling и extern «C» в C ++

C ++ поддерживает перегрузку функций, т. Е. Может быть несколько функций с одинаковыми именами и различиями в параметрах. Как компилятор C ++ различает разные функции при генерации объектного кода — он меняет имена, добавляя информацию об аргументах. Этот метод добавления дополнительной информации к именам функций называется Name Mangling . Стандарт C ++ не определяет какой-либо конкретный метод искажения имен, поэтому разные компиляторы могут добавлять различную информацию к именам функций.

Рассмотрим следующие объявления функции f ()

int  f (void) { return 1; }

int  f (int)  { return 0; }

void g (void) { int i = f(), j = f(0); }

Компилятор C ++ может поменять имена выше на следующие (Источник: Wiki )

int  __f_v (void) { return 1; }

int  __f_i (int)  { return 0; }

void __g_v (void) { int i = __f_v(), j = __f_i(0); }

Как обрабатывать символы C при линковке из C ++?
В C имена не могут быть искажены, так как C не поддерживает перегрузку функций. Итак, как убедиться, что имя символа не изменилось, когда мы связываем код на C в C ++. Например, смотрите следующую программу на C ++, которая использует функцию printf () из C.

// Сохранить файл как .cpp и использовать компилятор C ++ для его компиляции

int printf(const char *format,...);

  

int main()

{

    printf("GeeksforGeeks");

    return 0;

}

Выход:

undefined reference to `printf(char const*, ...)'
        ld returned 1 exit status

Причина ошибки компилятора проста: имя printf изменяется компилятором C ++ и не находит определения функции с новым именем.

Решение проблемы — extern «C» в C ++. Когда некоторый код помещается во внешний блок «C», компилятор C ++ гарантирует, что имена функций не исправлены — что компилятор выдает двоичный файл с неизменными именами, как это сделал бы компилятор C.

Если мы изменим вышеуказанную программу на следующую, программа будет работать нормально и печатает «GeeksforGeeks» на консоли.

// Сохранить файл как .cpp и использовать компилятор C ++ для его компиляции

extern "C"

{

    int printf(const char *format,...);

}

  

int main()

{

    printf("GeeksforGeeks");

    return 0;

}

Выход:

GeeksforGeeks

Поэтому все заголовочные файлы в стиле C (stdio.h, string.h, .. и т. Д.) Имеют свои объявления в внешнем блоке «C».

#ifdef __cplusplus 

extern "C" {

#endif

    / * Объявления этого файла * /

#ifdef __cplusplus
}
#endif

Ниже приведены основные моменты, обсужденные выше.
1. Поскольку C ++ поддерживает перегрузку функций, необходимо добавить дополнительную информацию к именам функций (так называемое искажение имен), чтобы избежать конфликтов в двоичном коде.
2. Имена функций не могут быть изменены в C, так как C не поддерживает перегрузку функций. Чтобы избежать проблем со связыванием, C ++ поддерживает внешний блок «C». Компилятор C ++ гарантирует, что имена внутри внешнего блока «C» не изменятся.

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

Рекомендуемые посты:

Название Mangling и extern «C» в C ++

0.00 (0%) 0 votes