реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
Serega Doc
сообщение Oct 20 2005, 14:00
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 267
Регистрация: 11-11-04
Из: Одесса
Пользователь №: 1 103



Есть main.c и proc.c
в const.h объявляю константы и дефайны

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

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

получается что строка
#includ "const.h"
проходит два раза и в main.c и в proc.c.
Как избавится от ошибки.
Компилятор ICC v7
Go to the top of the page
 
+Quote Post
beer_warrior
сообщение Oct 20 2005, 14:14
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380



Так называемый защитный код:
в .h файле
#ifndef _xxx_h
#define _xxx_h
тело файла
#endif
это гарантирует проход препроцессора по телу файла 1 раз


--------------------
Вони шукають те, чого нема,
Щоб довести, що його не існує.
Go to the top of the page
 
+Quote Post
damir2
сообщение Oct 20 2005, 14:15
Сообщение #3


Участник
*

Группа: Свой
Сообщений: 47
Регистрация: 12-07-05
Пользователь №: 6 725



Оставь один раз #includ "const.h" в main.c
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 20 2005, 20:19
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



1. Используйте условную компиляцию. Т.е. конструкцию типа
Код
#ifndef _I_CONST_DEF
  ...
  #define _I_CONST_DEF   1
#endif

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

и включайте главный хидер во все файлы проекта, где используются эти функции.
Go to the top of the page
 
+Quote Post
haker_fox
сообщение Oct 20 2005, 23:26
Сообщение #5


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



#ifndef CONST_H //если константа не определена, то
#define CONST_H //определить константу
//Код хедера
#endif

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

Вместо CONST_H соответственно для другого файла - другое имя, например MAIN_H


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
GrayCat
сообщение Oct 21 2005, 06:03
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 263
Регистрация: 7-10-05
Из: UA
Пользователь №: 9 342



Цитата(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 помещать только объявления, т.е. то, что не порождает код и не вызывает выделения памяти.


--------------------
Gray©at
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Oct 24 2005, 06:50
Сообщение #7


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



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

Чего не скажешь о С++, например, где в хедерах обьявляются классы.
А это иногда весьма неслабая часть кода.!
Go to the top of the page
 
+Quote Post
GrayCat
сообщение Oct 24 2005, 07:33
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 263
Регистрация: 7-10-05
Из: UA
Пользователь №: 9 342



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

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

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


--------------------
Gray©at
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Oct 24 2005, 07:44
Сообщение #9


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



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

Я имел в виду не выделение памяти, а порождение кода.
Особенно когда методы класса являются встроенными (инлайновыми).
Или когда применяются шаблоны функций, тело которых иначе как в хедерах и не обьявишь.
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Oct 24 2005, 07:55
Сообщение #10


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



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

Константа _xxx_DEF обьявляется только в одном файле *.c, где происходит выделение под них памяти. Все же остальные файлы включающие данный хедер, будут видеть только обьявления.
При желании можно написать макрос, который сделает всё это автоматически.
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 24 2005, 14:55
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



IgorKossak, понятно что это можно, но для чего это нужно? cranky.gif Если не трудно, то приведите пример из практики где было обосновано такое объявление глобальных переменных?
Go to the top of the page
 
+Quote Post
GrayCat
сообщение Oct 25 2005, 07:02
Сообщение #12


Местный
***

Группа: Свой
Сообщений: 263
Регистрация: 7-10-05
Из: UA
Пользователь №: 9 342



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

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

Но я лично предпочитаю традиционный вариант wink.gif


--------------------
Gray©at
Go to the top of the page
 
+Quote Post
Old1
сообщение Oct 25 2005, 17:35
Сообщение #13


Знающий
****

Группа: Свой
Сообщений: 697
Регистрация: 26-07-05
Из: Могилев
Пользователь №: 7 095



Цитата(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

по крайней мере так работает...
Go to the top of the page
 
+Quote Post
-Tумблер-
сообщение Oct 26 2005, 12:33
Сообщение #14


Частый гость
**

Группа: Свой
Сообщений: 146
Регистрация: 4-11-04
Из: Московская область
Пользователь №: 1 040



Цитата(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 - создать ее у себя.
А если был определен( те файл определений подключен к проекту) - использовать оттудова.


--------------------

- ЗАМЕНЯТЬ ДЕТАЛИ НА ХОДУ ВОСПРЕЩАЕТСЯ !!! -
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Oct 26 2005, 14:45
Сообщение #15


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Нет, правильно всё-таки
Код
#ifdef _xxx_DEF
т. к. константа определяется только в одном месте и поэтому переменные должны определяться только один раз.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 24th June 2025 - 08:55
Рейтинг@Mail.ru


Страница сгенерированна за 0.01488 секунд с 7
ELECTRONIX ©2004-2016