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

 
 
 
Reply to this topicStart new topic
> Почему не работает #define, проект в IAR
aspID
сообщение May 22 2012, 15:10
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714



Проект из нескольких файлов. В основном стоят директивы #define, во включаемых заголовочниках проверяется через #ifndef и не видится. Помогает только явное указание в свойствах проекта.

F_CPU объявлен через свойства проекта, используется в delay.h - не вызывает ошибок

USART_BUF_SIZE объявлен через директиву #define в main.c и используется в USART.h - вызывает ошибку.


Прикрепленные файлы
Прикрепленный файл  src.7z ( 2.8 килобайт ) Кол-во скачиваний: 19
 
Go to the top of the page
 
+Quote Post
mdmitry
сообщение May 22 2012, 15:48
Сообщение #2


Начинающий профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648



Цитата(aspID @ May 22 2012, 19:10) *
F_CPU объявлен через свойства проекта, используется в delay.h - не вызывает ошибок

USART_BUF_SIZE объявлен через директиву #define в main.c и используется в USART.h - вызывает ошибку.

Лучше define объявлять в заголовочном файле. Там ему место, если использовать надо в нескольких местах.
Да и стражи включения лучше использовать классическим образом.


--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post
_Артём_
сообщение May 22 2012, 16:04
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(aspID @ May 22 2012, 18:10) *
Проект из нескольких файлов. В основном стоят директивы #define, во включаемых заголовочниках проверяется через #ifndef и не видится. Помогает только явное указание в свойствах проекта.
F_CPU объявлен через свойства проекта, используется в delay.h - не вызывает ошибок

Оба этих способа нормальны и допустимы.


.
Go to the top of the page
 
+Quote Post
aspID
сообщение May 22 2012, 16:11
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714



Цитата(mdmitry @ May 22 2012, 22:48) *
Лучше define объявлять в заголовочном файле.


Предлагаете сделать дополнительный .h ?

Цитата(mdmitry @ May 22 2012, 22:48) *
Да и стражи включения лучше использовать классическим образом.

Здесь, к сожалению, не понял, что имели в виду. Кроме #pragma once еще дополнять конструкцию ifndef-define?

Цитата(_Артём_ @ May 22 2012, 23:04) *
Поэтому при использовании в нескольких местах #include "main.c"


Компилятор делает в нескольких местах такую директиву? Или я чего-то неправильно понял
Go to the top of the page
 
+Quote Post
SSerge
сообщение May 22 2012, 16:34
Сообщение #5


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

Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528



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

Лучше сделать, например, так: собрать все настройки проекта в один .h-файл (константы, определения ног, светодиодов, вкл/выкл различных опций программы и тому подобное) и включать его первым во все .c-файлы проекта.


--------------------
Russia est omnis divisa in partes octo.
Go to the top of the page
 
+Quote Post
_Артём_
сообщение May 22 2012, 16:45
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(aspID @ May 22 2012, 19:11) *
Предлагаете сделать дополнительный .h ?

Тоже вариант: его можно менять в зависимости от надобности и включить в USART.h - будет как конфиг проекта.

Цитата(aspID @ May 22 2012, 19:11) *
Здесь, к сожалению, не понял, что имели в виду. Кроме #pragma once еще дополнять конструкцию ifndef-define?


Просто чаще встречается такая конструкция(хотя кому-то может и наоборот):
Код
#ifndef usart_tx_rx_h__
#define usart_tx_rx_h__


#endif



Цитата(aspID @ May 22 2012, 19:11) *
Или я чего-то неправильно понял

Не...это я что-то неправильно понял.

Цитата
USART_BUF_SIZE объявлен через директиву #define в main.c и используется в USART.h - вызывает ошибку.


А точно ошибку, а не warning? У меня откомпилировалось.
P.S. но как Си-проект, а вы хотите Си++?
Go to the top of the page
 
+Quote Post
aspID
сообщение May 22 2012, 16:57
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714



Цитата(SSerge @ May 22 2012, 23:34) *
Я Вам сейчас одну умную вещь скажу, только не обижайтесь (с)
Вроде спрашиваю не для того, чтоб обижаться beer.gif
Цитата(_Артём_ @ May 22 2012, 23:45) *
Тоже вариант: его можно менять в зависимости от надобности и включить в USART.h - будет как конфиг проекта.

Вообще, предполагалось, что USART.h - самостоятельная и отдельная вещь, навроде библиотеки, которую в дальнейшем можно будет использовать в разных проектах БЕЗ внесения в нее правок и необходимости перекомпиляции blush.gif
Цитата(_Артём_ @ May 22 2012, 23:45) *
Просто чаще встречается такая конструкция(хотя кому-то может и наоборот):
Код
#ifndef usart_tx_rx_h__
#define usart_tx_rx_h__
...
#endif

Вообще,
Код
#pragma once

имеет то же назначение. Если компилятор без косяков этом месте biggrin.gif
Хотя, бывают и особо мнительные случаи использования
Код
#pragma once
#ifndef usart_tx_rx_h__
#define usart_tx_rx_h__
...
#endif

Цитата(_Артём_ @ May 22 2012, 23:45) *
А точно ошибку, а не warning? У меня откомпилировалось.

Так ворнинг руками и выдается. Просто сделана "затычка", которая если не видит - предупреждает и переобъявляет. И в данном контексте раз не видит - значит, ошибка. [Моя ошибка имеется в виду, только пока до конца не понимаю, в чем]
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение May 22 2012, 17:11
Сообщение #8


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Да,
Код
#pragma once
нынче можно сказать стала обыденностью и поддерживается всеми современными компиляторами.
А по поводу организации модулей могу предложить метод.
Каждый модуль состоит из 3 файлов:
module.c
module.h
module_conf.h - он включён инклюдом в module.h.

Таким макаром файлы
module.c
module.h
лежат в библиотеке в единственном экземпляре и подключаются ко всем проектам, в которых в них есть нужда, а
module_conf.h копируется в каждый проект и модифицируется под него (например задаёт размер фифо для уара и кол-во активных уартов ну и т.д. и т.п)


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
_Артём_
сообщение May 22 2012, 17:28
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(aspID @ May 22 2012, 19:57) *
Вообще, предполагалось, что USART.h - самостоятельная и отдельная вещь, навроде библиотеки, которую в дальнейшем можно будет использовать в разных проектах БЕЗ внесения в нее правок и необходимости перекомпиляции blush.gif


Цитата(aspID @ May 22 2012, 19:57) *
Так ворнинг руками и выдается. Просто сделана "затычка", которая если не видит - предупреждает и переобъявляет. И в данном контексте раз не видит - значит, ошибка. [Моя ошибка имеется в виду, только пока до конца не понимаю, в чем]


Ну раз хотите как "библиотеку" то можно так: создаёте файл допустим usart_cfg.h:
Код
#pragma once

#define USART_BUF_SIZE 32


Файл usart_cfg.h вставляете в USART.h(include "usart_cfg.h") - так он будет виден в main.c и USART.c с одним и тем же USART_BUF_SIZE.

Но перекомпилироваться всё равно будет...

Цитата(aspID @ May 22 2012, 19:57) *
Вообще,
Код
#pragma once

имеет то же назначение. Если компилятор без косяков этом месте biggrin.gif

В общем - да, смысл тот же.



Цитата(demiurg_spb @ May 22 2012, 20:11) *
лежат в библиотеке в единственном экземпляре и подключаются ко всем проектам, в которых в них есть нужда, а
module_conf.h копируется в каждый проект и модифицируется под него (например задаёт размер фифо для уара и кол-во активных уартов ну и т.д. и т.п)

Может сразу template.

Цитата(demiurg_spb @ May 22 2012, 20:11) *
Каждый модуль состоит из 3 файлов:
module.c
module.h
module_conf.h - он включён инклюдом в module.h.

И чтобы сократить количество файлов которые нужно редактировать можно завести один файл io_modules_conf.h, включить его во все module.h - и все настройки в нём сразу и менять.
Go to the top of the page
 
+Quote Post
aspID
сообщение May 22 2012, 17:33
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714



надо же... даже все ваши идеи понял! sm.gif
Действительно, хорошие мысли! Надо взять на вооружение...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 22 2012, 19:06
Сообщение #11


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (aspID @ May 22 2012, 19:57) *
Вообще,
CODE
#pragma once

имеет то же назначение. Если компилятор без косяков этом месте biggrin.gif
Назначение то же, но работает не всегда так же. Не все компиляторы корректно обрабатывают разноименные ссылки (жесткие и/или символьные) на один и тот же файл. В принципе - да, это будет косяк компилятора.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
aspID
сообщение May 23 2012, 02:35
Сообщение #12


Местный
***

Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714



Цитата(aspID @ May 23 2012, 00:33) *
Действительно, хорошие мысли! Надо взять на вооружение...
Вот что получилось с утреца: USART_conf.h
Код
#ifdef _COMMON_CONFIG_PRESENT_
  #include "config.h"
#else
  // Put parameters here
#endif
config.h
Код
#define _COMMON_CONFIG_PRESENT_
#define ENABLE_BIT_DEFINITIONS
#define USART_BUF_SIZE 32 // Cyrillic SMS len 70
В дальнейшем так и буду поступать, спасибо! a14.gif
Go to the top of the page
 
+Quote Post
mdmitry
сообщение May 23 2012, 08:04
Сообщение #13


Начинающий профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648



Цитата(aspID @ May 23 2012, 06:35) *
Код
#ifdef _COMMON_CONFIG_PRESENT_
  #include "config.h"
#else
  // Put parameters here
#endif


Код
#define _COMMON_CONFIG_PRESENT_
#define ENABLE_BIT_DEFINITIONS
#define USART_BUF_SIZE 32 // Cyrillic SMS len 70
В дальнейшем так и буду поступать, спасибо! a14.gif

А Вы только в config.h определили #define _COMMON_CONFIG_PRESENT_? Тогда проверка не имеет смысла, всегда ветка else выполняется, так как символ не определен ранее.
И посмотрите, пожалуйста, как написаны заголовочные файлы, например, для Вашего компилятора. Посмотрите, что ещё подключается автоматически с файлом описания применяемого микропроцессора. Такой подход весьма распространен и, на мой взгляд, удобен.


--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post
aspID
сообщение May 23 2012, 10:47
Сообщение #14


Местный
***

Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714



Цитата(mdmitry @ May 23 2012, 15:04) *
А Вы только в config.h определили #define _COMMON_CONFIG_PRESENT_?


Нет, только в опциях проекта. В файле config.h сделана проверка и #error, если вдруг _COMMON_CONFIG_PRESENT_ не определен. Иначе у препроцессора возникает неоднозначность, какой из .c файлов проекта первый обнаружит этот файл: если библиотечный, то "сие не есть гуд", а вот если main.c - хорошо. Поэтому, добивался однозначности.

Прикрепленный файл  src.zip ( 11.81 килобайт ) Кол-во скачиваний: 69
- Вот так.

Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 7th July 2025 - 23:32
Рейтинг@Mail.ru


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