Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как подключаются h и с файлы
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Serega Doc
Есть main.c и proc.c
в const.h объявляю константы и дефайны

в proc.c выненсены процедуры которые используются в main.c

в proc.c используются константы из const.h

получается что строка
#includ "const.h"
проходит два раза и в main.c и в proc.c.
Как избавится от ошибки.
Компилятор ICC v7
beer_warrior
Так называемый защитный код:
в .h файле
#ifndef _xxx_h
#define _xxx_h
тело файла
#endif
это гарантирует проход препроцессора по телу файла 1 раз
damir2
Оставь один раз #includ "const.h" в main.c
rezident
1. Используйте условную компиляцию. Т.е. конструкцию типа
Код
#ifndef _I_CONST_DEF
  ...
  #define _I_CONST_DEF   1
#endif

2. Все функции описывайте в главном хидере проекта с помощью определения extern
Код
extern unsigned int MyFunc (void)

и включайте главный хидер во все файлы проекта, где используются эти функции.
haker_fox
#ifndef CONST_H //если константа не определена, то
#define CONST_H //определить константу
//Код хедера
#endif

Когда компилятор будет во-второй раз цеплять хедер, он его не подцепит, т.к. константа CONST_H уже определена (при первом проходе)

Вместо CONST_H соответственно для другого файла - другое имя, например MAIN_H
GrayCat
Цитата(Serega Doc @ Oct 20 2005, 16:00)
Есть main.c и proc.c
в const.h объявляю константы и дефайны
*

Что понимается под "константами" в const.h? Если собственно объявление и инициализация констант, типа
Код
// in "const.h":
const int SomeConst=0x55AA;
то конечно линкер будет ругаться, т.к. при сборке окажется что SomeConst определена во всех файлах, куда включен const.h.

Более правильно объявить константу в хедере:
Код
// in "const.h":
extern const int SomeConst;
а определить и инициализировать ее в одном из *.C-файлов:
Код
// in "proc.c":
const int SomeConst=0x55AA;
Тогда компилятор при компиляции всех файлов, куда включен const.h, будет знать, что SomeConst где-то определено, будет знать его тип, а собственно память под SomeConst выделит только в proc.c. А линкер уже потом разберется что к чему, и ссылки на SomeConst из всех объектников привяжет к единому месту.

Вообще, есть такое общее правило: в заголовочных файлах *.h помещать только объявления, т.е. то, что не порождает код и не вызывает выделения памяти.
IgorKossak
Цитата(GrayCat @ Oct 21 2005, 09:03)
...Вообще, есть такое общее правило: в заголовочных файлах *.h помещать только  объявления, т.е. то, что не порождает код и не вызывает выделения памяти.
*

Чего не скажешь о С++, например, где в хедерах обьявляются классы.
А это иногда весьма неслабая часть кода.!
GrayCat
Цитата(IgorKossak @ Oct 24 2005, 08:50)
Цитата(GrayCat @ Oct 21 2005, 09:03)
...Вообще, есть такое общее правило: в заголовочных файлах *.h помещать только  объявления, т.е. то, что не порождает код и не вызывает выделения памяти.
*

Чего не скажешь о С++, например, где в хедерах обьявляются классы.
А это иногда весьма неслабая часть кода.!
*

Насколько я ничего не понимаю в Ц++, объявление классов память никак не выделяет. Это происходит только при создании экземпляров класса, что выполняется уже в *.C-файлах.
IgorKossak
Цитата(GrayCat @ Oct 24 2005, 10:33)
Насколько я ничего не понимаю в Ц++, объявление классов память никак не выделяет. Это происходит только при создании экземпляров класса, что выполняется уже в *.C-файлах.
*

Я имел в виду не выделение памяти, а порождение кода.
Особенно когда методы класса являются встроенными (инлайновыми).
Или когда применяются шаблоны функций, тело которых иначе как в хедерах и не обьявишь.
IgorKossak
Никто почему-то не расскажет ещё об одной технике обьявления/определения переменных в хедерах.
Помимо охранных констант, исключающих повторное включение файла иногда бывает удобно в одном файле и определять и обьявлять переменные (экземпляры класса).
Код
#ifndef _xxx_DEF
...
unsigned int My_Int_Var;
...
#else
...
extern unsigned int My_Int_Var;
...
#endif

Константа _xxx_DEF обьявляется только в одном файле *.c, где происходит выделение под них памяти. Все же остальные файлы включающие данный хедер, будут видеть только обьявления.
При желании можно написать макрос, который сделает всё это автоматически.
rezident
IgorKossak, понятно что это можно, но для чего это нужно? cranky.gif Если не трудно, то приведите пример из практики где было обосновано такое объявление глобальных переменных?
GrayCat
Цитата(rezident @ Oct 24 2005, 16:55)
IgorKossak, понятно что это можно, но для чего это нужноcranky.gif Если не трудно, то приведите пример из практики где было обосновано такое объявление глобальных переменных?
*

Ну, например, такая техника удобна тем, что объявление и определение переменной оказываются "близко" друг к другу (в пределах 3-х строк), и при необходимости модификации ее типа или имени изменения быстро вносятся в обе строки. При обычном "разнесении" переменной в .h и .c приходится открывать 2 файла и в них выискивать нужные места.

Но я лично предпочитаю традиционный вариант wink.gif
Old1
Цитата(IgorKossak @ Oct 24 2005, 10:55)
Никто почему-то не расскажет ещё об одной технике обьявления/определения переменных в хедерах.
Помимо охранных констант, исключающих повторное включение файла иногда бывает удобно в одном файле и определять и обьявлять переменные (экземпляры класса).
Код
#ifndef _xxx_DEF
...
unsigned int My_Int_Var;
...
#else
...
extern unsigned int My_Int_Var;
...
#endif

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

Здесь ИМХО ошибка вкралась, вместо
Код
#ifndef _xxx_DEF

нужно
Код
#ifdef _xxx_DEF

по крайней мере так работает...
-Tумблер-
Цитата(Old1 @ Oct 25 2005, 20:35)
Здесь ИМХО ошибка вкралась,
#ifndef _xxx_DEF
...
unsigned int My_Int_Var;
...
#else
...
extern unsigned int My_Int_Var;
...
#endif[/code]
Константа _xxx_DEF обьявляется только в одном файле *.c, где происходит выделение под них памяти.Здесь ИМХО ошибка вкралась, вместо
Код
#ifndef _xxx_DEF

нужно
Код
#ifdef _xxx_DEF

по крайней мере так работает...
*


А я так понял , что Игорь прав.
Те если не было определено неадера _xxx_DEF
с переменной unsigned int My_Int_Var - создать ее у себя.
А если был определен( те файл определений подключен к проекту) - использовать оттудова.
IgorKossak
Нет, правильно всё-таки
Код
#ifdef _xxx_DEF
т. к. константа определяется только в одном месте и поэтому переменные должны определяться только один раз.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.