2013-04-18 3 views
7

Я хотел бы знать, где лучше поставитьГде лучшее место, чтобы поставить #ifdef __cplusplus Экстерн «C» {#endif

#ifdef __cplusplus 
extern "C" { 
#endif 

в заголовочном файле C.

В начале или после всех других включает. Зачем ?

+1

Я бы сказал, что после включений, потому что почему бы вы поместили внутри внутри ifdef? –

ответ

9

На это нет строгих правил, но обратите внимание на следующее.

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

Просто знайте, что идея extern «C» заключается в том, что он заставляет компилятор генерировать C дружественную связь. В противном случае код, скомпилированный с помощью компилятора C++, ищет искаженные имена для сопоставления в архивах, скомпилированных с компилятором C, и не может их найти.

+0

Третий пример: На самом деле есть библиотеки C, автору которых не было никакого отношения к C++, и просто оставил материал extern «C». Не могли бы вы теперь изменить внешние заголовки или включить немодифицированные заголовки, завернутые вашим собственным «extern» C »? Я лично предпочитаю последнее ... – Aconcagua

9

Эта конструкция используется, чтобы сделать ваши имена доступными для C линкера (краткое объяснение)

Так очевидно, что вы хотите использовать его вокруг только ваши вещи.

Как это:

#ifndef MY_INCLUDE_H_ // include guard 
#define MY_INCLUDE_H_ 

#include <...> // dependencies 
#include "..." 

#ifdef __cplusplus 
extern “C” { 
#endif 

// ... your types, methods, variables 

#ifdef __cplusplus 
} 
#endif 

#endif // MY_INCLUDE_H_ 
+0

Или наоборот: разрешить использование C-функций в коде C++ ... – Aconcagua

+0

@Aconcagua, о котором следует позаботиться во включенных заголовках C, но в крайнем случае да. Но в .cpp-файле, а не в заголовке. – Offirmo

+0

Ну, поток тоже отмечен как «C», поэтому с этой точки зрения ваш пример мог бы быть также заголовком C, если бы вы не включили какой-либо экслитический заголовок C++ или не использовали какой-то эксклюзивный код на C++ ... – Aconcagua

1

extern "C" влияет на то, что код компилируется. Заголовки, которые являются , предназначены для составления, которые должны быть скомпилированы как C, так и C++ будут управлять самими extern "C". Вы должны never wrap a #include директива в блоке extern "C": если заголовок, который был задействован, был скомпилирован в обоих случаях, когда ваша директива является избыточной, и если она не была предназначена для использования в обоих направлениях, это ошибка.

+0

Что вы имели в виду под «спроектированы» и «не был дизайн»? – Vincent

1
  • extern "C" влияет на связь. Когда функции C++ скомпилированы, у них есть свои имена, поэтому перегрузка на C++ возможна. Таким образом, имя функции изменяется на основе типов и количества параметров, поэтому две функции с одинаковыми именами будут иметь два разных символьных имени.

  • Код внутри extern «C» по-прежнему является кодом на C++. Есть ограничения на то, что вы можете сделать во внешнем блоке «C», но все они связаны с привязкой.

+0

Возможно, вы захотите отказаться от термина «C++ name mangling» в вашем непонятном ответе –

+0

@Jaap Versteegh Почему нужно отказаться от термина, который является термином, используемым для идентификации такого поведения? Если кто-то хочет больше узнать о том, что происходит и почему, это тот термин, который они должны использовать для поиска дополнительной информации. – hobb

+0

@hobb Я хотел сказать «заглянуть», как в «добавить». Название mangling было * not * указано в ответе, и, как вы говорите, это имя для этого поведения. –

Смежные вопросы