Перейти к содержанию
    

Прозрачность программы для компилятора

Насколько я понимаю, инклюд, обьявленный в начале файла должен быть виден во всех последующих инклюдах программы. Согласно Кернигану и Риччи, предпроцессор заменяет директиву #include на содержимое файла, на который она указывает. Однако в ИАРе для успешной компиляции некоторые инклюды приходится втыкать чуть ли не в каждый файл проекта. Плюс к тому, с-шные файлы вообще не участвуют в инклюдах, а обращение к их функциям происходит через прототипы функций одноименных хедеров. Нестыковочка.

 

Подскажите пожалуйста, как можно избавиться от сабжевой проблемы, в чем могут быть ее причины? Общие ответы типа "в кривости кода" - не в счет.

 

 

PS Пользую IAR EWARM 4.40A

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Однако в ИАРе для успешной компиляции некоторые инклюды приходится втыкать чуть ли не в каждый файл проекта.
Каждый .c -файл, входящий в проект, компилируется отдельно (и называется единицей компиляции). При этом компилятор понятия не имеет о других файлах (единицах компиляции) и, следовательно, о включенных в них инклюдах. Все инклюды, которые вам могут понадобиться в этом .c надо в него включить.
Плюс к тому, с-шные файлы вообще не участвуют в инклюдах, а обращение к их функциям происходит через прототипы функций одноименных хедеров. Нестыковочка.
Стыковочка. На этапе компиляции из заголовочных файлов берутся прототипы (описания) функций, благодаря которым компилятор знает, что существует функция с таким именем, знает с какими параметрами функция должна вызываться и значение какого типа должна возвращать. За соблюдением этих типов и следит компилятор. А уже линкер в места вызова функций подставляет конкретные адреса. При этом тело и место вызова могут находиться в разных единицах компиляции. Можете поискать в гугле по ключевым словам "раздельная компиляция".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Проблема не в кривости кода а в недопонимании.

Во первых, как Вы правильно сказали

предпроцессор заменяет директиву #include на содержимое файла
, но это в том файле, где этот include стоИт. С какой стати он должен быть виден в других файлах проекта, где Вы его ставить не желаете?

Компилятор в каждый момент времени работает только с одним С/С++ файлом проекта и учитывает только входящие в него include. Нестыковки здесь нет.

Во вторых, если в файле несколько include, то каждый последующий видит содержимое предыдущих, но не наоборот, и это логично. Таким образом получается возможная зависимость от порядка. Чтобы её избежать применяются различные ходы вроде включения include в хедеры (и это тоже логично, поскольку есть некоторые зависимости), при этом все хедеры должны иметь охранные директивы, о чём многократно писалось на форуме.

 

PS Как всегда, не успел за Сергеем Борщом ;)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кроме выше сказанного, могу предложить вариант создания файла all.h

со всеми включениями, а потом включать только его.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Благодарю.

Начинает доходить. :)

 

Значит любой с-файл включенный в проект будет компилироваться и отгрызать место даже если я закоментирую инклюд с его хедером??

 

Насчет охранных директив и порядка следования я в курсе. Тем больше удивлялся когда повторное включение хедера с охранной директивой изменяло результат компиляции. Но теперь ясно.

 

alexander55 отличная идея! На первый взгляд. Почему тогда такой прием широко не используется? Врядли для того чтобы сократить время компиляции.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Значит любой с-файл включенный в проект будет компилироваться и отгрызать место даже если я закоментирую инклюд с его хедером??

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

alexander55 отличная идея! На первый взгляд. Почему тогда такой прием широко не используется? Врядли для того чтобы сократить время компиляции.

Используется широко.

Файл all.h

#ifndef allH

#define allH

...

#endif

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

alexander55 отличная идея! На первый взгляд. Почему тогда такой прием широко не используется? Врядли для того чтобы сократить время компиляции.

Отличную идею нужно довести до конца!

1 склеим все хедеры в один

2 склеим все сишники в один

3 склеим склееное в один супер сишник

4 выкинем лишнее, оставшееся от хедеров

Получаем удовольствие :08:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Отличную идею нужно довести до конца!

1 склеим все хедеры в один

2 склеим все сишники в один

3 склеим склееное в один супер сишник

4 выкинем лишнее, оставшееся от хедеров

Получаем удовольствие :08:

Давайте без фанатизма и экстремизма. :biggrin:

Но все мечтают видеть все, сразу, вместе и чтобы было все ясно и наглядно !

PS. И хорошо бы, чтобы и работало без вопросов. :07:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

отличная идея! На первый взгляд. Почему тогда такой прием широко не используется? Врядли для того чтобы сократить время компиляции.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Это желательно, но не обязательно (но стремиться к этому надо).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кроме выше сказанного, могу предложить вариант создания файла all.h

со всеми включениями, а потом включать только его.

 

Мне эта идея раньше нравилась тоже, но сейчас уже нет, после того, как я некоторое время поработал по такой системе.

Если проект достаточно большой, содержит несколько десятков исходников, начинает напрягать пересборка всего при малейшей правке в любом хедере.

Например, последние проекты на Fujitsu FFMC, которые я делал, выливались где-то в 100 кБ бинарного кода. Время компиляции всех файлов проекта занимает порядка минуты. Это уже существенно, чтобы такой подход начал напрягать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Полностью присоединяюсь к Andy Mozzhevilov - избыточные включения - перекомпиляция всего при любом изменении.

Кроме того, если вы явно включаете только то, что нужно - вы четко знаете зависимости. Если вы включаете все - у вас все зависит от всего, ни о каких зависимостях говорить не получается. А в сколь-нибудь больших проектах без инкапсуляции очень сложно...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я согласен. Не может быть все со знаком плюс, чем то приходится поступиться.

Главное - не принципами ! :biggrin:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Линкер выдает такую ошибку:

Error[e27]: Entry "AT91F_ADC_CfgModeReg" in module BasicWEB ( ..\BasicWEB.r79 ) redefined in module SAM7_EMAC ( ..\SAM7_EMAC.r79 )

В обоих указан инклюд, в котором находится конфликтующая ф-я. Причом она инлайновая.

#include <lib_AT91SAM7X256.h>

С АЦП я вообще не работаю. Охранные директивы в этом хедере есть. В чем проблема?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...