2015-01-04 6 views
6

Я создаю файл main.c, чтобы использовать функции из нескольких разных файлов .h. Некоторые из этих файлов .h (или, вернее, их .c исходных файлов) используют те же самые функции (стандартный, но также и некоторые другие)Должен ли я включать или отключать одни и те же заголовки в разных файлах c, которые, в свою очередь, являются заголовками, используемыми в основном файле?

Мой вопрос: все в порядке, если я просто включу их один раз для всех заголовков файлы в моем main.c, или я должен позволить каждому файлу .h включать их отдельно и не включать их в мой main.c (учитывая, что я использую только функции из этих файлов заголовков)?

Или должен ли я сделать оба?

Как это сделать сейчас:

dist.c: 

#include "dist.h" 
#include <stdio.h> 
#include <unistd.h> 
#include "rpiGpio.h" 
#include <pthread.h> 
#include <wiringPi.h> 
#include <softPwm.h> 

Тогда для другого:

cmps.c: 

#include "cmps.h" 
#include <stdint.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <math.h> 
#include "rpiGpio.h" 

Тогда в моем main.c:

#include <stdio.h> 
#include <stdlib.h> 
#include "dist.h" 
#include "cmps.h" 

Заранее спасибо!

ответ

6

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

Если в вашем примере dist.h содержит <stdio.h>, вы не должны полагаться на это наружу dist.h. Если вы измените dist.h так, чтобы он больше не зависел от <stdio.h> и удалил #include, тогда ваша программа переломается.

+0

Звучит очень логично, как вы его объясняете, не мог это сделать из-за того, что я читал об этом. Благодаря! – Guinn

3

Я думаю, что ответ «это зависит». Пока вы согласны, я думаю, что все в порядке. Некоторые преимущества и недостатки различных подходов:

  1. Включение дважды в системный заголовок не вызывает побочных эффектов (из-за защитных ограждений); включая ваши собственные заголовки дважды, также не должны вызывать проблем, если вы также используете защитники заголовков. Однако, возможно, это может замедлить компиляцию.

  2. В некоторых случаях, особенно в старых уни версиях, порядок включения заголовков имеет значение (к сожалению). Иногда порядок #define с (например, #define _GNU_SOURCE) делает вопрос в отношении #include. Я также имел это случается с Linux включают файлы для различных внутренних бит сети (я теперь забываю, что). По этой причине, это хорошая идея всегда включать вашу систему включает (и #define s они проверяют) в последовательной манере.

  3. Один из способов сделать это - включить всю вашу систему в один отдельный файл include и включить их из каждого файла .c; это приводит к такому же результату, который вы получили бы с autoconf и его сгенерированным config.h. Однако он может излишне включать файлы, замедляющие компиляцию.

  4. Некоторые говорят, что включает в себя системные заголовки над вашими собственными включенными. Хотя это часто рассматривается как хорошая практика, оно не работает отлично, если ваши собственные ссылочные типы файлов .h, определенные в системе, включают в себя, например, stdint.h определяет int32_t.Если вы включите это в свой файл .h, вы вернетесь к потенциальной проблеме с включением заказа и внесите ли вы свой #define _GNU_SOURCE в нужное место.

  5. Поэтому мой личный стиль кодирования должны иметь config.h эквивалент, который входит все .h файлов и (для ровного) всех .c файлов в качестве первого включает, в котором содержится вся соответствующая система включает в себя. Это не идеальное время компиляции, но для этого нужны прекомпилированные заголовки. Я обычно устраиваю систему в алфавитном порядке, если только нет причин.

  6. Альтернатива - (осторожно) делать это по файлу, как предлагает @meagar.

+0

Мне нравятся разные подходы и ответ, хотя часть ответа @meagar предполагает, что каждый файл должен «работать» независимо от собственного списка зависимостей заголовков и, следовательно, не должен работать, если вы меняете включения в файл main.c, это прямой ответ на мой вопрос! – Guinn

+0

Включая '' foo.h "' дважды в некоторый файл типа '' foo.c "' (и только один раз в других местах) - это метод, помогающий проверить, что '' foo.h'' правильно защищен. Похоже на большие точки зрения. – chux

+0

1) Компиляция вряд ли пострадает, включив один и тот же заголовочный файл более одного раза. 2) Если ваш компилятор не принимает во внимание порядок, немедленно отпустите его. Оно сломано. 3) Глобальные заголовки - это плохая привычка, которую разделяют слишком многие люди. 4) Не смешивая систему и локальный заголовок, вы можете избежать большой работы с #defines. 5) Глобальные файлы заголовков ... config.h предназначены для вещей, которые вы не можете надежно предсказать при написании кода; не лениться. – Clearer

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

  • Нет связанных вопросов^_^