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

Как подключаются h и с файлы

Есть main.c и proc.c

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

 

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

 

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

 

получается что строка

#includ "const.h"

проходит два раза и в main.c и в proc.c.

Как избавится от ошибки.

Компилятор ICC v7

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


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

Так называемый защитный код:

в .h файле

#ifndef _xxx_h

#define _xxx_h

тело файла

#endif

это гарантирует проход препроцессора по телу файла 1 раз

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


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

1. Используйте условную компиляцию. Т.е. конструкцию типа

#ifndef _I_CONST_DEF
  ...
  #define _I_CONST_DEF   1
#endif

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

extern unsigned int MyFunc (void)

и включайте главный хидер во все файлы проекта, где используются эти функции.

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


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

#ifndef CONST_H //если константа не определена, то

#define CONST_H //определить константу

//Код хедера

#endif

 

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

 

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

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


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

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

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


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

...Вообще, есть такое общее правило: в заголовочных файлах *.h помещать только  объявления, т.е. то, что не порождает код и не вызывает выделения памяти.

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

А это иногда весьма неслабая часть кода.!

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


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

...Вообще, есть такое общее правило: в заголовочных файлах *.h помещать только  объявления, т.е. то, что не порождает код и не вызывает выделения памяти.

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

А это иногда весьма неслабая часть кода.!

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

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


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

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

Я имел в виду не выделение памяти, а порождение кода.

Особенно когда методы класса являются встроенными (инлайновыми).

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

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


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

Никто почему-то не расскажет ещё об одной технике обьявления/определения переменных в хедерах.

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

#ifndef _xxx_DEF
...
unsigned int My_Int_Var;
...
#else
...
extern unsigned int My_Int_Var;
...
#endif

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

При желании можно написать макрос, который сделает всё это автоматически.

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


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

IgorKossak, понятно что это можно, но для чего это нужно? :cranky: Если не трудно, то приведите пример из практики где было обосновано такое объявление глобальных переменных?

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


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

IgorKossak, понятно что это можно, но для чего это нужно?  :cranky: Если не трудно, то приведите пример из практики где было обосновано такое объявление глобальных переменных?

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

 

Но я лично предпочитаю традиционный вариант ;)

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


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

Никто почему-то не расскажет ещё об одной технике обьявления/определения переменных в хедерах.

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

#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

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

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


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

Здесь ИМХО ошибка вкралась,

#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 - создать ее у себя.

А если был определен( те файл определений подключен к проекту) - использовать оттудова.

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


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

Нет, правильно всё-таки

#ifdef _xxx_DEF

т. к. константа определяется только в одном месте и поэтому переменные должны определяться только один раз.

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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