Зачем предотвращать изменение имен файлов C

Примечание: мой вопрос касается моих знаний, я не пытаюсь решить конкретную проблему.

я изучал использование библиотеки C в проекте CPP, чтобы предотвратить искажение имени компилятора:

#ifdef __cplusplus
extern "C" {
#endif

1- но я также читал, что компилятор С++ не искажает файлы .c. так зачем заморачиваться?

2- если у вас была библиотека из +500 c файлов. (заголовки + c файлы). как вы автоматически добавляете в них этот Extern "C"? есть ли инструмент, который автоматизирует этот процесс?


person Hasan alattar    schedule 15.01.2019    source источник
comment
Я сомневаюсь, что вы видите это в заголовке (.h), а не в реализации (.c).   -  person apple apple    schedule 15.01.2019
comment
@appleapple кажется, я видел их как в файлах .c, так и в файлах .h.   -  person Hasan alattar    schedule 15.01.2019
comment
Это не решает вопрос, но extern "C" говорит об изменении имен так же, как это делает компилятор C. Компиляторы C обычно добавляют подчеркивание в начале имени, хотя тот, который использовал я, добавлял подчеркивание на другом конце.   -  person Pete Becker    schedule 15.01.2019


Ответы (3)


  1. Компилятор c++ может не изменять имена в файлах .c, но он определенно искажает файлы, включенные в файлы .cpp, поэтому в файлах заголовков это необходимо.
  2. вы можете просто использовать extern "C"{ file content here }, это можно легко сделать во многих инструментах.

Я пишу для вас cmd-скрипт (.bat)

ВНИМАНИЕ: это приведет к перезаписи существующих файлов, сделайте резервную копию!

@ECHO OFF
for /R %%f in (*.c,*.h) do (
   @echo extern "C" { > temp
   @echo. >> temp
   @type %%f >> temp
   @echo. >> temp   
   @echo } >> temp
   @type temp > %%f
   @echo processed %%f
)
person apple apple    schedule 15.01.2019
comment
привет, я собираюсь пометить это как ответ, хотя эти инструменты предназначены для этой конкретной проблемы или ее текстового инструмента с чем-то вроде плагина в Notepad ++ или что-то в этом роде? / или они поставляются с IDE? Я исследовал для них, но не мог найти. - person Hasan alattar; 15.01.2019
comment
@Hasanalattar Я имею в виду некоторые общие инструменты. Я пишу для вас cmd-скрипт (.bat). (надеюсь, вы также используете окна :) - person apple apple; 15.01.2019
comment
@Hasanalattar: Вы не можете найти такой инструмент, потому что в нем обычно нет необходимости. - person MSalters; 15.01.2019
comment
Я не думаю, что этот простой сценарий-оболочка будет работать с чем-то вроде #include <math.h>, который в C++ указывает на некоторые перегруженные функции. - person aschepler; 15.01.2019
comment
Но, видимо, я ошибаюсь, так как быстрый тест не дает мне ошибок компилятора. Интересный... - person aschepler; 15.01.2019
comment
@aschepler, это потому, что, вероятно, где-то есть extern "C++", которые перезаписывают extern "C" - person apple apple; 15.01.2019
comment
@aschepler на самом деле extern c просто не работает с функциями перегрузки - person Hasan alattar; 15.01.2019
comment
@aschepler, так как это не случай ОП, я бы хотел оставить свой ответ как есть, но это хороший момент :) - person apple apple; 15.01.2019
comment
@aschepler для полноты, вот документ для спецификаций вложенных связей - person apple apple; 15.01.2019
comment
@appleapple Да, я вижу, что в моем math.h есть как минимум один #ifdef __cplusplus extern "C++" { и некоторые другие специфические для компилятора приемы, которые также могут быть связаны. Хорошо, что они убедились, что такие вещи работают, но я не уверен, действительно ли стандарт C++ говорит, что это должно работать. - person aschepler; 16.01.2019
comment
@aschepler без оболочки, компилятор все равно сможет скомпилировать эти #includes, я не понимаю, почему это не сработает. - person apple apple; 16.01.2019

Ответ «яблоко-яблоко» обычно неверен.

Компилятор C++ по определению компилирует C++. Некоторые компиляторы являются компиляторами C/C++ или поддерживают еще больше языков (на ум приходит GCC). Они могут использовать расширение файла в качестве подсказки, но обычно вы также можете выбрать один конкретный язык. Например. gcc -x c++ выбирает компилятор Gnu C++ даже для файлов .c.

Что касается существующей библиотеки C, поскольку у вас есть исходные файлы, вам нет необходимости предотвращать искажение имен. Скомпилируйте библиотеку тем же компилятором, что и ваше приложение. Это приводит к тому, что искажение имени будет идентичным. Инструменты не нужны.

Я также подозреваю, что вы можете подумать, что extern "C" означает "компилировать как код C". Это не так. Это означает «скомпилировать этот код C++ так, чтобы его внешний интерфейс был совместим с C». Вы по-прежнему получаете все возможности C++ внутри.

person MSalters    schedule 15.01.2019
comment
для первой части вы имеете в виду, что обычно gcc по умолчанию выбирает компилятор c для файлов .c, поэтому он не искажает их. даже если они будут включены в файл cpp? вторая часть была полностью в моей голове (я имею в виду, очевидно, почему меня должно волновать, что мой компилятор будет искажать функции c.. он знает, что делать..) спасибо за разъяснение :) - person Hasan alattar; 15.01.2019
comment
Я не уверен, что вполне справедливо классифицировать ответ Apple как в целом неправильный, хотя я согласен с тем, что, когда они сказали, что компилятор c++ не может... они наверняка имели в виду ваш компилятор (который способен создавать как C++, так и C) - кроме того, что это правильно, нет? OFC весь ваш ответ верен, но пропускает важный аспект включенных заголовков, используемых кодом, по-разному написанным на любом языке. - person Lightness Races in Orbit; 15.01.2019

[Дополнительный ответ]

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

// Foo.cpp
extern "C" {
   #include "Foo.c"
}

Вы говорите своему компилятору C++ скомпилировать Foo.cpp. Сначала он запустит препроцессор, который вставит Foo.c в блок extern "C" { }.

person MSalters    schedule 15.01.2019