Ошибка: переопределение «статической переменной» в заголовочных файлах C - PullRequest
0 голосов
/ 02 июля 2018

У меня есть несколько статических переменных (скажем, var1 и var2), объявленных в двух разных файлах. Переменные имеют одинаковые имена в обоих файлах. Некоторые переменные (скажем, var1) не инициализируются в своем объявлении, а некоторые - (var2), как показано ниже.

file1.h

static bool var1;
static bool var2 = false;

file2.h

static bool var1;
static bool var2 = false;

Насколько я понимаю, статические переменные ограничены только теми файлами c (или h файлами), в которых они объявлены, поэтому я должен быть уверен, что в нескольких заголовочных файлах одинаковые имена переменных. Но когда я компилирую код, я получаю сообщение об ошибке «Переопределение var2», только для переменных, которые были инициализированы.

  1. Почему эта ошибка возникает только для var2?
  2. Моя реализация в порядке?

Edit: поскольку некоторые упоминают об использовании ключевого слова extern, я хотел бы уточнить, что var1 и var2 должны иметь разные значения в разных файлах c и должны быть ограничены только их соответствующими файлами,

Ответы [ 3 ]

0 голосов
/ 02 июля 2018

Почему эта ошибка возникает только для var2? , если вы включите file1.h и file2.h в один и тот же исходный файл test.cpp, тогда var2 будет иметь два определения, и компилятор не сможет выбрать, какой один взять и выдает ошибку.

Чтобы избежать этого, объявите var2 как extern в заголовочном файле .h и определите в соответствующем исходном файле .cpp.

Хотя в случае var1 это просто declaration, а не definition, поэтому он не выдаст ошибку, т. Е. Возможно многократное объявление.

Также объявление static, как

static bool var1;

означает, что переменная var1 видна только в текущей единице компиляции.

Примечание: переменная static имеет внутреннюю связь, т.е. скрывает переменную static от других единиц перевода. Хотя static переменные могут быть defined в нескольких единицах перевода.

Переменная

и extern, имеющая внешнюю связь, т.е. переменная extern будет видна другим единицам перевода, но переменная extern должна быть определена только в одной единице перевода.

0 голосов
/ 02 июля 2018

Если исходный файл включает и file1.h, и file2.h, он будет иметь несколько определений var2. Вот что вызывает ошибку.

Вместо того, чтобы объявлять / определять эти статические переменные в заголовочных файлах, поместите их непосредственно в необходимые исходные файлы языка Си. Таким образом, вам не придется иметь дело с несколькими определениями.

0 голосов
/ 02 июля 2018

Нет. Многократное объявление var1 нормально, но множественное определение из var2 - нет. Вы не можете инициализировать переменную дважды ... даже если значения одинаковы.

Я решаю подобные проблемы, используя препроцессор, например:

#if !defined(MY_APP__VARS_DEFINED)
static int var1, var2=0;
#define MY_APP__VARS_DEFINED
#endif

Даже тогда я не рекомендую дублировать определения в нескольких заголовочных файлах. Это проблема технического обслуживания. Рано или поздно кто-то может изменить это начальное значение в одном заголовке и не найти все другие заголовки, в которых он определен. Это также усложняет переименование («рефакторинг»). (... и нарушает принцип DRY .)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...