Не работает ifndef

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Аватара пользователя
wss60
Потрогал лапой паяльник
Сообщения: 350
Зарегистрирован: Пт сен 10, 2010 20:48:01
Откуда: Минск

Не работает ifndef

Сообщение wss60 »

Не могу разобраться, почему при объявлении переменных в файле "lcd.h" компилятор выдаёт ошибку.
Если объявлять переменные в “lcd.с” то компилируется без ошибок.
Такое ощущение, что не работает ifndef?

Код: Выделить всё

arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: src/lcd.o:C:\Users\Alex\Desktop\arm/inc/lcd.h:14: multiple definition of `backColor';
 src/main.o:C:\Users\Alex\Desktop\arm/inc/lcd.h:14: first defined here
arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: src/lcd.o:C:\Users\Alex\Desktop\arm/inc/lcd.h:13: multiple definition of `fontColor';
 src/main.o:C:\Users\Alex\Desktop\arm/inc/lcd.h:13: first defined here
collect2.exe: error: ld returned 1 exit status
makefile:118: recipe for target 'main.elf' failed
make: *** [main.elf] Error 1
Вложения
project.zip
(295.31 КБ) 182 скачивания
Реклама
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: Не работает ifndef

Сообщение WiseLord »

В .h файлах переменные лучше не определять. Иначе, для каждого .c файла, который включает эту переменную, будет создана её копия в промежуточном б объектном файле. А при линковке нескольких файлов в один исполняемый естественным образом возникнет эта ошибка. Ликер не будет знать, какую из копий этой переменной использовать.
Реклама
Аватара пользователя
wss60
Потрогал лапой паяльник
Сообщения: 350
Зарегистрирован: Пт сен 10, 2010 20:48:01
Откуда: Минск

Re: Не работает ifndef

Сообщение wss60 »

Как тогда получить доступ к переменным в "lcd.c" из "main.c" или любого другого места?
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: Не работает ifndef

Сообщение COKPOWEHEU »

объявить саму переменную в *.c файле, а ее прототип с модификатором extern в *.h файле.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
AVI-crak
Прорезались зубы
Сообщения: 202
Зарегистрирован: Сб янв 09, 2016 15:51:17
Контактная информация:

Re: Не работает ifndef

Сообщение AVI-crak »

[uquote="wss60",url="/forum/viewtopic.php?p=3795365#p3795365"]Такое ощущение, что не работает ifndef?[/uquote]
Нельзя определение записывать в теле условия, после - можно. И вообще, для таких целей есть хороший макрос.

Код: Выделить всё

#ifndef _namefile

#ifdef __cplusplus
 extern "C" {
#endif /* __cplusplus */

/// объявления функций, переменных, и всего остального...

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* _namefile */
#define _namefile
Реклама
Аватара пользователя
wss60
Потрогал лапой паяльник
Сообщения: 350
Зарегистрирован: Пт сен 10, 2010 20:48:01
Откуда: Минск

Re: Не работает ifndef

Сообщение wss60 »

Заработало! Спасибо всем! Теперь более менее стало понятно, как работать с библиотеками.
Реклама
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: Не работает ifndef

Сообщение WiseLord »

[uquote="COKPOWEHEU",url="/forum/viewtopic.php?p=3795409#p3795409"]объявить саму переменную в *.c файле, а ее прототип с модификатором extern в *.h файле.[/uquote]Либо для получения / модификации переменной сделать для неё функции геттер/сеттер, а не пытаться работать с ней напрямую. Часто это ещё и более компактный код продуцирует.
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: Не работает ifndef

Сообщение NStorm »

[uquote="wss60",url="/forum/viewtopic.php?p=3795389#p3795389"]Как тогда получить доступ к переменным в "lcd.c" из "main.c" или любого другого места?[/uquote]
Объявление extern. Прочитайте еще чем объявление от определения в C отличается. Это 2 разных термина.
Стандартно как-то обычно делается:
unit.h:

Код: Выделить всё

#ifndef UNIT_H
#define UNIT_H

extern int a;
#endif
unit.c:

Код: Выделить всё

#include "unit.h"

...
int a = 123;
unit2.c:

Код: Выделить всё

#include "unit.h"
...
a = 222;
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: Не работает ifndef

Сообщение COKPOWEHEU »

[uquote="WiseLord",url="/forum/viewtopic.php?p=3795526#p3795526"]Часто это ещё и более компактный код продуцирует.[/uquote]
Хм. А за счет чего?
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: Не работает ifndef

Сообщение WiseLord »

Возможно, из-за того, что на машинном уровне используются более коротких локальных jump-ы и "лёгкие" регистровые переменные.

В принципе, это можно проверить. В начале функции считать глобальную переменную в локальную, поработать с ней локально, вернуть назад результат. Практически уверен, что это будет быстрее и компактнее, чем постоянно работать с внешней global переменной.
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: Не работает ifndef

Сообщение COKPOWEHEU »

[uquote="WiseLord",url="/forum/viewtopic.php?p=3796195#p3796195"]Возможно, из-за того, что на машинном уровне используются более коротких локальных jump-ы и "лёгкие" регистровые переменные.[/uquote]
В таком случае "длинный jmp" идет не на переменную, а на функцию. Учитывая накладные расходы на вызов функции, быстрее не будет.
[uquote="WiseLord",url="/forum/viewtopic.php?p=3796195#p3796195"]В принципе, это можно проверить. В начале функции считать глобальную переменную в локальную, поработать с ней локально, вернуть назад результат. Практически уверен, что это будет быстрее и компактнее, чем постоянно работать с внешней global переменной.[/uquote]
И в чем разница между чтение-модификация-запись и get()-модификация-set()? Буферизовать-то и глобальную переменную никто не мешает, равно как вызывать геттер-сеттер на каждое обращение.
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: Не работает ifndef

Сообщение WiseLord »

Разница в том что в get()/set() можно дополнительно проверки на валидность какие-нибудь делать.
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: Не работает ifndef

Сообщение COKPOWEHEU »

Конечно. С точки зрения структуры программы, разграничения доступа и многопоточности (для работы в прерываниях, например) это вполне может пригодиться.
Но я-то спрашивал про скорость доступа и размер кода.
jcxz
Мудрый кот
Сообщения: 1726
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: Не работает ifndef

Сообщение jcxz »

[uquote="WiseLord",url="/forum/viewtopic.php?p=3795375#p3795375"]В .h файлах переменные лучше не определять.[/uquote]Автор говорил про "объявление", а не про "определение". Что такое то и другое можете узнать, открыв любой учебник по си. А объявляют глобальные переменные как правило в .h.
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: Не работает ifndef

Сообщение WiseLord »

Да, объявляют глобальные переменные, как правило в .h. Но, как я и говорил, определять их там (как это сделал топикстартер, неправильно использовав термин) лучше не стоит.

А вообще, тема некорректная. #ifndef _MODULE_NAME/ #define _MODULE_NAME_ - это совсем не про ошибки линковки. Это работает только в пределах компиляции одного модуля, как разрешение проблемы множественного включения одних и тех же объявлений.

И "живёт" определённая в .h неглобальная переменная без проблем только до тех пор, пока этот .h не включён в как минимум два файла. И #ifdef тут никакой роли не играет.
Аватара пользователя
AlanDrakes
Прорезались зубы
Сообщения: 236
Зарегистрирован: Пн июл 04, 2016 16:51:22
Откуда: Россия, Омск

Re: Не работает ifndef

Сообщение AlanDrakes »

А ещё переменные можно объявлять с ключевым словом 'extern' в любом месте файла, в любых файлах (.c / .h)
extern char some_variable;

Но в этом случае, хотя бы в одном переменная должна быть физически объявлена (без extern)
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: Не работает ifndef

Сообщение NStorm »

Можно - не значит нужно. Принято любые объявления переменных записывать в хидерах, включая extern. Писать объявления в .c - моветон.
Ответить

Вернуться в «ARM»