переопределение переменной, встроенный c

Я работаю над встроенным проектом c, и у меня возникают проблемы с переопределением глобальной переменной.

Я разделил объявления и определения функций на несколько файлов .h и .c. Многим из этих функций требуется доступ к глобальным переменным, которые определены в global_vars.h. Следовательно, в начале файлов заголовков, внутри раздела #ifndef, #define, "global_vars.h". Если я этого не сделаю, как вы можете себе представить, я получаю кучу ошибок неопределенных переменных.

Однако, хотя global_vars.h имеет #ifndef _GLOBAL_VARS_H_ #define ... #endif, я получаю ошибки переопределения для всех глобальных переменных. Я предполагаю, что когда компоновщик пытается связать различные объектные файлы, он видит переопределение из-за #include «global_vars.h» во всех файлах «blah_blah.h». Насколько я понимаю, эту проблему решает #ifndef ...

Я что-то не замечаю?

заранее спасибо


person Trey    schedule 16.06.2011    source источник
comment
Вам нужно объявить переменные в заголовке и определить их только в одном исходном файле.   -  person forsvarir    schedule 17.06.2011
comment
Ваш global_vars.h файл должен объявлять все переменные как extern, а затем фактически определять их в отдельном модуле. Полагаю, ты этого не делаешь?   -  person Jeff Mercado    schedule 17.06.2011
comment
ты прав. Я попробую это спасибо   -  person Trey    schedule 17.06.2011
comment
В качестве примечания: если в вашем проекте есть глобальный файл с неконстантными глобальными переменными, объявленными в области видимости файла, это обычно указывает на то, что что-то во всей структуре программы в корне неверно.   -  person Lundin    schedule 17.06.2011


Ответы (3)


Компоновщик никогда ничего не видит в файле global_vars.h, если только - плохие новости! - некоторые глобальные переменные действительно определены в этом файле. global_vars.h должен содержать только объявления этих глобальных переменных, но никогда (ну, почти никогда) их определения.

В global_vars.h вы должны иметь такие объявления, как:

extern int some_global;

Вам не разрешается иметь:

int some_global;

Если у вас есть определения в global_vars.h, то да, они будут многократно определены во время компоновки, потому что каждый из файлов .c, который #includes global_vars.h будет иметь собственное определение каждой определенной переменной.

Все определения extern глобальных объектов обязательно должны быть в каком-нибудь файле .c. Обычно не имеет значения, какой файл .c. Часто все определения глобальных переменных находятся в файле с именем (сюрприз!) Global_vars.c.

Поэтому убедитесь, что в global_vars.h нет определений глобальных переменных, и вы будете в хорошей форме.

person Pete Wilson    schedule 16.06.2011

Не рекомендуется определять глобальные объекты в H-файле. Лучше, если вы сделаете это в файле C или C ++ и включите и файл H в другие модули с этими глобальными объектами как внешними. Вот так >>>

Мой модуль c файл

unsigned short int AGLOBAL = 10; // definer and initializer

void MyFunc(void)
{
  AGLOBAL+=1; // no need to include anything here cause is defined above
  // more .....

}

Мой H-файл globals.h

// this is to include only once
#ifndef MYH
#define MYH
extern unsigned short int AGLOBAL; // no value in here!

#endif

Другой модуль c файл

#include globals.h

char SomeOtherFunc(void)
{
  AGLOBAL+=10; // ok cause its defined by globals.h
  // do more....
}
person ruhalde    schedule 28.06.2011

Итак, позвольте мне начать с того, что ключевое слово extern применяется к переменным C (объектам данных) и функциям C. В основном ключевое слово extern расширяет видимость переменных C и функций C. Вероятно, поэтому он был назван extern.

Использование extern с функциями C. По умолчанию перед объявлением и определением функции C ставится «extern». Это означает, что даже несмотря на то, что мы не используем extern с объявлением / определением функций C, он там присутствует. Например, когда мы пишем.

int foo(int arg1, char arg2);

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

extern int foo(int arg1, char arg2);

То же самое и с определением функции C (определение функции C означает запись тела функции). Поэтому всякий раз, когда мы определяем функцию C, в начале определения функции присутствует extern. Поскольку объявление может быть выполнено любое количество раз, а определение может быть выполнено только один раз, мы можем заметить, что объявление функции может быть добавлено в несколько файлов C / H или в один файл C / H несколько раз. Но мы замечаем фактическое определение функции только один раз (то есть только в одном файле). И поскольку extern расширяет видимость для всей программы, функции можно использовать (вызывать) где угодно в любом из файлов всей программы при условии, что объявление функции известно. (Зная объявление функции, компилятор C знает, что определение функции существует, и приступает к компиляции программы). Итак, это все, что касается extern с функциями C.

  1. Объявление можно делать любое количество раз, а определение - только один раз.

  2. Ключевое слово extern используется для расширения видимости переменных / функций ().

  3. Поскольку по умолчанию функции видны во всей программе. Использование extern не требуется при объявлении / определении функции. Его использование избыточно.

  4. Когда extern используется с переменной, она только объявляется как неопределенная.

  5. В качестве исключения, когда внешняя переменная объявляется с инициализацией, она также используется как определение переменной.

person Moorthi Muthu    schedule 10.08.2015