|
|
  |
вопросы по IAR, В поисках идеального компилятора |
|
|
|
Nov 1 2005, 09:56
|

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

|
[quote=&-rey,Nov 1 2005, 09:28] [quote=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, где происходит выделение под них памяти. Все же остальные файлы включающие данный хедер, будут видеть только обьявления. При желании можно написать макрос, который сделает всё это автоматически. мне как раз понадобилась данная рекомендация и я в *.h поставил так Код #ifndef _*_h #define _*_h char a=5; #else extern char a; #endif но компилятор ругается и говорит что переменная a определяется в 2-х файлах Но вроде бы должно было быть определение как переменной a только в одном файле, а в другом где подключен *.h уже просто определение как extern. получается что "защитный код" не работает. Ложки не существует ? или я что-то не так сделал ??? [/quote] Существует, смотри здесь, в самом конце... ЗЫ (на всякий случай подробно) в хидере нужно так сделать: Код #ifdef _*_h char a=5; #else extern char a; #endif а в модуле перед #include <хидер> вставить: Код #define _*_h .
|
|
|
|
|
Nov 1 2005, 11:56
|
Местный
  
Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064

|
И все равно никак  Перейдем на конкретный пример имеем в main.c Код #include "Clear.h" #include "main.h"
__task main( void ) { while(1) { a = 6; Clear(); } } В main.h Код #include <io8535.h> #include <avr_macros.h> #include <inavr.h> в Clear.c Код #include "main.h" #include "Clear.h"
void Clear(void) { a = 0; } и в Clear.h Код #ifndef _Clear_h #define _Clear_h void Clear(void); #endif
#ifdef _Clear_h char a; #else extern char a; #endif так вот ругается : Error[e27]: Entry "a" in module Clear ( C:\Clear\Debug\Obj\Clear.r90 ) redefined in module main ( C:\ Clear\Debug\Obj\main.r90 )
|
|
|
|
|
Nov 1 2005, 12:02
|

Участник

Группа: Новичок
Сообщений: 48
Регистрация: 6-05-05
Пользователь №: 4 784

|
Цитата(&-rey @ Nov 1 2005, 15:56) Error[e27]: Entry "a" in module Clear ( C:\Clear\Debug\Obj\Clear.r90 ) redefined in module main ( C:\ Clear\Debug\Obj\main.r90 ) ИМХО, переменные запихивать в хидеры - это бред.
--------------------
|
|
|
|
|
Nov 1 2005, 12:19
|
Местный
  
Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064

|
Цитата(G}{OST @ Nov 1 2005, 15:02) Цитата(&-rey @ Nov 1 2005, 15:56) Error[e27]: Entry "a" in module Clear ( C:\Clear\Debug\Obj\Clear.r90 ) redefined in module main ( C:\ Clear\Debug\Obj\main.r90 ) ИМХО, переменные запихивать в хидеры - это бред. возможно, я пока начинающий в С. перенес в Clear.c и имеем такой вариант: Error[Pe020]: identifier "a" is undefined C:\Clear\main.c 8
|
|
|
|
|
Nov 1 2005, 12:42
|
Местный
  
Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064

|
Цитата(G}{OST @ Nov 1 2005, 15:32) так в хидере пропиши как extern и включи хидер в тот модуль ну да, если отдельно то все работает, но вопрос то именно как это сделать через #ifndef Просто так намного удобнее, и не надо при использовании своих библиотек вспоминать какие переменные как определять. Все автоматом.
|
|
|
|
|
Nov 1 2005, 12:48
|

Участник

Группа: Новичок
Сообщений: 48
Регистрация: 6-05-05
Пользователь №: 4 784

|
Цитата(&-rey @ Nov 1 2005, 16:42) Цитата(G}{OST @ Nov 1 2005, 15:32) так в хидере пропиши как extern и включи хидер в тот модуль ну да, если отдельно то все работает, но вопрос то именно как это сделать через #ifndef Просто так намного удобнее, и не надо при использовании своих библиотек вспоминать какие переменные как определять. Все автоматом.  Лично я делаю проекты так, чтобы использование внешних переменных было только в исключительных случаях. Иначе глюков потом не оберёшься.
--------------------
|
|
|
|
|
Nov 1 2005, 13:13
|
Местный
  
Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064

|
Цитата(G}{OST @ Nov 1 2005, 15:48) Цитата(&-rey @ Nov 1 2005, 16:42) Цитата(G}{OST @ Nov 1 2005, 15:32) так в хидере пропиши как extern и включи хидер в тот модуль ну да, если отдельно то все работает, но вопрос то именно как это сделать через #ifndef Просто так намного удобнее, и не надо при использовании своих библиотек вспоминать какие переменные как определять. Все автоматом.  Лично я делаю проекты так, чтобы использование внешних переменных было только в исключительных случаях. Иначе глюков потом не оберёшься. Ладно, тогда такой вопрос. Обработчик клавиатуры имеет два регистра Keyb_flag и Old_Keyb_flag. Макрос сравнивает код клавиши со значением в Keyb_flag и Old_Keyb_flag для принятия решения об нажатии или отжатии. Как в таком случае должны быть объявлены Keyb_flag и Old_Keyb_flag чтобы макрос мог вызываться из любой другой подпрограммы. ? Я думаю что для этого они должны быть глобальными, хотя может и нет, как быть в этом варианте ???
|
|
|
|
|
Nov 1 2005, 13:38
|

Участник

Группа: Новичок
Сообщений: 48
Регистрация: 6-05-05
Пользователь №: 4 784

|
Цитата(&-rey @ Nov 1 2005, 17:13) Ладно, тогда такой вопрос. Обработчик клавиатуры имеет два регистра Keyb_flag и Old_Keyb_flag. Макрос сравнивает код клавиши со значением в Keyb_flag и Old_Keyb_flag для принятия решения об нажатии или отжатии. Как в таком случае должны быть объявлены Keyb_flag и Old_Keyb_flag чтобы макрос мог вызываться из любой другой подпрограммы. ? Я думаю что для этого они должны быть глобальными, хотя может и нет, как быть в этом варианте ??? Если позволяют ресурсы, лучше сделать процедуру, а не макрос. Иначе, если ресурсов в обрез, сделать внешними эти переменные. Объявить процедуру или переменные можно в хидере, который включается куда надо.
--------------------
|
|
|
|
|
Nov 1 2005, 13:46
|
Местный
  
Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064

|
Цитата(G}{OST @ Nov 1 2005, 16:38) Цитата(&-rey @ Nov 1 2005, 17:13) Ладно, тогда такой вопрос. Обработчик клавиатуры имеет два регистра Keyb_flag и Old_Keyb_flag. Макрос сравнивает код клавиши со значением в Keyb_flag и Old_Keyb_flag для принятия решения об нажатии или отжатии. Как в таком случае должны быть объявлены Keyb_flag и Old_Keyb_flag чтобы макрос мог вызываться из любой другой подпрограммы. ? Я думаю что для этого они должны быть глобальными, хотя может и нет, как быть в этом варианте ??? Если позволяют ресурсы, лучше сделать процедуру, а не макрос. Иначе, если ресурсов в обрез, сделать внешними эти переменные. Объявить процедуру или переменные можно в хидере, который включается куда надо. Да дело даже не в ресурсах. Например как параметр макроса я задаю код клавиши и указатель на функцию. В этом случае макрос - самое оно. ReleaseKey(Key,*pFunction) А обявлять отдельно можно, но я хотел бы как предлагалось IgorKossak, а то еще надо лишний файлик делать, специально для main.c.  А хочется именно как описано но вот не работает, а почему непонятно. Создается впечатление что #ifdef вообще никак компилятором не обрабатывается. что у меня не так написано ?
|
|
|
|
|
Nov 1 2005, 13:56
|

Участник

Группа: Новичок
Сообщений: 48
Регистрация: 6-05-05
Пользователь №: 4 784

|
Цитата(&-rey @ Nov 1 2005, 17:46) А обявлять отдельно можно, но я хотел бы как предлагалось IgorKossak, а то еще надо лишний файлик делать, специально для main.c.  А хочется именно как описано но вот не работает, а почему непонятно. Создается впечатление что #ifdef вообще никак компилятором не обрабатывается. что у меня не так написано ? Если #ifdef не обрабатывается компилером, значит на момент обработки препроцессором этой директивы параметр не был задефайнен.
--------------------
|
|
|
|
|
Nov 1 2005, 13:59
|
Частый гость
 
Группа: Свой
Сообщений: 100
Регистрация: 19-01-05
Из: Москва
Пользователь №: 2 064

|
Вообще лучше делать так: Код /* Module name: globals.h */ #ifdef __GLOBAL_DECLARATIONS #define EXTERN #else #define EXTERN extern #endif
EXTERN U8 a; компилятор вообще-то компилирует каждый файл по отдельности, ничего не зная о том,какие макросы уже определены в других файлах. Поэтому и ругается. В файле main.c (и только в нем) должно быть определение до включения файла globals.h Код /* Module name: main.c */ #define __GLOBAL_DECLARATIONS #include "globals.h" Насчет файла globals.h в учебниках пишут прямо противоположное, я в своем стандарте оформления кода требую его использовать в виде, описанном выше. #ifndef пишется, чтобы не было переопределения макросов в случае вложения заголовочных файлов.
|
|
|
|
|
Nov 1 2005, 16:58
|
Частый гость
 
Группа: Свой
Сообщений: 100
Регистрация: 19-01-05
Из: Москва
Пользователь №: 2 064

|
Цитата(sergeeff @ Nov 1 2005, 19:10) Ну а не проще ли в файле global.c (и только в нем)объявить необходимые в проекте глобальные переменные, а в global.h их же продекларировать как external ? Где нужны эти переменные - #include "global.h". не проще - раньше так и делал, в случае изменений приходится править оба файла.
|
|
|
|
|
Nov 1 2005, 17:55
|

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

|
Цитата(&-rey @ Nov 1 2005, 14:56) И все равно никак  Перейдем на конкретный пример имеем в main.c Код #include "Clear.h" #include "main.h"
__task main( void ) { while(1) { a = 6; Clear(); } } В main.h Код #include <io8535.h> #include <avr_macros.h> #include <inavr.h> в Clear.c Код #include "main.h" #include "Clear.h"
void Clear(void) { a = 0; } и в Clear.h Код #ifndef _Clear_h #define _Clear_h void Clear(void); #endif
#ifdef _Clear_h char a; #else extern char a; #endif так вот ругается : Error[e27]: Entry "a" in module Clear ( C:\Clear\Debug\Obj\Clear.r90 ) redefined in module main ( C:\ Clear\Debug\Obj\main.r90 ) Исправь Clear.c: Код #include "main.h" #define _Clear_h #include "Clear.h"
void Clear(void) { a = 0; } и Clear.h: Код #ifdef _Clear_h void Clear(void); char a; #else extern char a; extern void Clear(void); #endif и должно заработать
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|