hosturik писал(а):у меня в файле main.h есть глобальные переменные, которые используются в нескольких сишных файлах и поэтому я подключаю этот main.h в этих файлах. Вроде же это логично?
Нет. Поскольку каждый .c файл компилируется отдельно, то при таком подходе в каждом полученном .o файле будет копия этой переменной. А уже потом линкер при совмещении .o файлов в .elf выдаст ошибку "multiple definition". И трюк с #ifndef MAIN_H / #define MAIN_H / #endif тут не поможет.
Так что, как уже подсказали, нужно использовать модификатор extern. Возможно два равноценных варианта:
1) В одном .c файле объявить переменную как обычно, в других с extern. Неудобство в том, что в каждом из новых .c файлов, которым нужна эта переменная, придётся делать это объявление.
2) Обычно код оформляется в виде библиотек - парах файлов вроде module.c/module.h. Тогда в module.c переменная объявляется как обычно, а в module.h с extern, и тем самым она становится видимой во всех .c файлах, которые инклюдят этот хидер.
hosturik писал(а):А пока покопаюсь в чужих исходниках, может докопаюсь до истины.
Живой пример из одного моего проекта. Переменная tuner для доступа к параметрам тюнера определена в
tuner.c и объявлена в
tuner.h с модификатором extern. Любой
другой файл просто её использует.
Ещё один возможный подход - использование функций-геттеров (ну и сеттеров при необходимости). Т.е. в tuner.c было бы что-то вроде:
Код: Выделить всё
static Tuner_type tuner;
Tuner_type getTuner(void)
{
return tuner;
}
А в tuner.h вместо extern быо бы просто интерфейс функции
В нужном месте кода вместо прямого выхова глобальной переменной tuner использовалась бы локальная
Ну а дальше - как обычно.
Такой подход в больших проектах более правильный, т.к. глобальные переменные - это не очень безопасно. Но в проектах на МК часто (не всегда) глобальные переменные дают небольшой выигрыш в размере кода.