Переопределение переменной, встроенный c - PullRequest
2 голосов
/ 17 июня 2011

Я работаю над встроенным проектом 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 ... решает эту проблему.

Есть ли что-то, что я пропускаю?

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

Ответы [ 3 ]

7 голосов
/ 17 июня 2011

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

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

extern int some_global;

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

int some_global;

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

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

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

1 голос
/ 10 августа 2015

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

Использование extern с функциями на Си.По умолчанию перед объявлением и определением функции 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. Как исключение, когда externпеременная объявляется с инициализацией, она также принимается как определение переменной.

1 голос
/ 29 июня 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....
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...