У меня есть вопрос о директивах препроцессора в C и C ++.
У меня есть следующий код:
#ifdef __cplusplus
//part A
extern "C"{
// somecode here
}
#else
//part B
#endif
Я знаю, что компилятор c ++ предопределен, а компилятор __cplusplus — нет.
И я поместил этот набор кода в файл заголовка c, и файл c ++ будет включать этот файл заголовка c. И мой вопрос: если файл скомпилирован компилятором c ++, он скомпилирует часть A, а если скомпилируется компилятором ac, он скомпилирует часть B, но обычно мы используем этот код для создания файла c ++ и c файл взаимодействует друг с другом, если у нас есть такой код выше, я имею в виду, что у нас есть оба файла C и C ++ вместе, и мы используем компилятор gcc, как этот код компилируется? только часть А компилируется? или компилируется только часть B? или код разделен на две части, часть A компилируется для C ++, а часть B компилируется для файла C одновременно?
В проекте с несколькими исходными файлами заголовок не обрабатывается компилятором один раз.
Когда компилятор компилирует файл C ++, он читает этот файл и любые содержащиеся в нем заголовки (прямо или косвенно) и обрабатывает содержимое этих файлов, используя правила для C ++.
Когда компилятор компилирует файл C, он читает этот файл и любые содержащиеся в нем заголовки (прямо или косвенно) и обрабатывает содержимое этих файлов, используя правила для C.
Результат будет таким, как если бы код в вашем заголовочном файле появился отдельно в источнике C ++ и в источнике C.
если у нас есть такой код выше, я имею в виду, что у нас есть оба файла C и C ++ вместе, и мы используем компилятор gcc, как этот код компилируется? только часть А компилируется? или компилируется только часть B?
Это зависит от того, как компилируется модуль перевода, который #include заголовок. Если он компилируется как C ++, то часть A вступит в силу; если он компилируется как C, он будет частью B.
С gcc
, язык либо определяется расширением файла, либо может быть явно указан в командной строке:
-x language
Укажите явно язык для следующих входных файлов (вместо того, чтобы позволить компилятору выбирать значение по умолчанию на основе
суффикс имени файла). Эта опция применяется ко всем следующим входным файлам
до следующего-x
вариант.Возможные значения для языка: c
c-заголовок c-cpp-выход c ++ c ++ — заголовок c ++ — cpp-output цель-c
target-c-header цель-c-cpp-output цель-c ++
target-c ++ — заголовок target-c ++ — ассемблер cpp-output
ассемблер с cpp ada f77 f77-cpp-input f95 f95-cpp-input java
Прямой ответ: компилируется только та часть, которая соответствует текущему вызову компилятора.
Как правило, структура
#ifdef __cplusplus
extern "C" {
#endif
/* Definitions here */
#ifdef __cplusplus
}
#endif
в заголовочном файле. Таким образом, вы получаете совместимые определения на обоих языках. В этом случае файл реализации будет иметь чистый C и храниться в файле .c.
По умолчанию gcc распознает .C
, .cpp
, .cc
и несколько других расширений, таких как C ++ и .c
как C. Вы можете попробовать что-то более странное в вашем файле make, чтобы заставить его пройти через все пути, но в простом случае это так просто.
Концептуально C ++ преобразуется в код C путем искажения идентификаторов. Это повлияет на связывание. (на самом деле это было так, как это было сделано в прошлом, и если память мне не изменяет, это было сделано Cfront.
Итак, имея
#ifdef __cplusplus
extern "C" {
#endif
/* Definitions here */
#ifdef __cplusplus
}
#endif
У вас есть одинаковые определения для C и C ++. Вы не хотите, чтобы другие (Часть A & В твоем вопросе) как то глупо. Вы просто то же самое, если вы используете его для C и C ++.
extern "C"
bit сообщает компилятору C ++, что связывание предназначено для объектного кода, скомпилированного для C, поэтому не используйте магию C ++ и, таким образом, убедитесь, что связывание будет работать.