Можем ли мы использовать extern "C" в файле C без #ifdef __cplusplus? - PullRequest
8 голосов
/ 29 февраля 2012

Почему не следует указывать extern "C" для функции, которую необходимо определить как функцию C?Какое влияние это окажет на компилятор при компиляции файла как источника C?

Если на компилятор C не влияет, мы не можем просто определить функцию в заголовочном файле, как показано ниже, удалив#ifdef __cplusplus проверить?

extern "C" {
    int MyFunc();
}

Ответ на другой вопрос говорит, что необходим #ifdef, но я не понимаю, почему:

Относительно # 2: __cplusplus будет определен для любого модуля компиляции, который выполняется через компилятор C ++.Как правило, это означает, что файлы .cpp и любые файлы включены в этот файл .cpp.Один и тот же .h (или .hh или .hpp или what-have-you) может интерпретироваться как C или C ++ в разное время, если их содержат разные модули компиляции.Если вы хотите, чтобы прототипы в файле .h ссылались на имена символов C, то они должны иметь extern "C" при интерпретации как C ++, и они не должны иметь extern "C" при интерпретации как C - следовательно, #ifdef __cplusplusпроверка.

Ответы [ 2 ]

17 голосов
/ 29 февраля 2012

Конструкция extern "C" является конструкцией C ++ и не распознается компилятором C. Обычно выдается сообщение об ошибке синтаксиса.

Обычный трюк - определить макрос, например EXTERN_C, который будет расширяться до разных вещей, в зависимости от того, компилируете ли вы с помощью C или C ++. Например:

В общем заголовочном файле:

#ifdef __cplusplus
#define EXTERN_C extern "C" {
#define EXTERN_C_END }
#else
#define EXTERN_C
#define EXTERN_C_END
#endif

В других файлах:

EXTERN_C
int MyFunc(void);
EXTERN_C_END
2 голосов
/ 29 февраля 2012

Если вы скомпилируете исходный файл как C, он будет не распознавать extern "C" и, как правило, приведет к ошибке компиляции.

Если вы скомпилируете исходный файл как C ++,он будет распознавать extern "C", и правильные имена будут связаны.

Поэтому его можно использовать только надежно, чтобы указывать имена символов C для файлов, которые вы компилируете как C ++.

Если вы компилируете источники как C и C ++, или ваши интерфейсы предназначены для клиентов C и C ++, вам нужно будет указать это так или иначе, чтобы ваши клиенты получали правильные символы при связывании (и т. Д.).

Похожие: Вам разрешено писать extern "C++" - для переводов C ++.

...