C - статическая переменная, маскирующая глобальную переменную - PullRequest
0 голосов
/ 13 марта 2012

Взгляните на следующий фрагмент кода ...

File1.h

void somefunc(int);

File1.c

#include "File1.h"

extern int var;

void somefunc(int x)
{
   ......
   var ++;
   etc, etc,
   ....
   return;
}

File2.h

static int var;

void someotherfunc(int);

File2.c

#include "File2.h"
#include "File1.h"

int var;

void someotherfunc(int z)
{
   z = etc etc;
   var --;
   ......
   somefunc(z);
   .....
   return;
}

Приведенные выше четыре файла компилируются без проблем.Проблема возникает, когда я пытаюсь инициализировать переменную 'var'.Если 'var' инициализируется в File2.c, где это глобальная переменная, код компилируется без проблем.Но когда я пытаюсь инициализировать статическую переменную в File2.h, компилятор выдает ошибку, говоря, что «переменная« var »в File1.c не определена».Может кто-нибудь, пожалуйста, расскажите, что здесь происходит.

Я просто пытался понять концепцию статических переменных и натолкнулся на эту путаницу.Любая помощь будет оценена.

Ответы [ 2 ]

2 голосов
/ 13 марта 2012

Это не может быть статичным. Static означает, что его «видимость» (не официальный термин, но, вероятно, более понятный) ограничена исходным файлом C, в котором он появляется (в данном случае это File2.c).

Это означает, что при попытке связать вместе File1 и File2 компоновщик не сможет увидеть var в File2, поэтому вы получаете сообщение об ошибке.

Если вы хотите, чтобы он был доступен с File1.c, отбросьте «статический» бит. Фактически, поскольку в File2.c определено var, исключите всю строку из File2.h.

2 голосов
/ 13 марта 2012

static int var;

Это дает var внутреннюю связь в модуле перевода File2.c, что бы ни следовало (да, даже если следует объявление extern).

Таким образом, если первое увиденное объявление будет static int var, то в этой единице перевода var будет всегда внутренним, и, следовательно, недоступным для других единиц перевода.

6.2.2-4

Для идентификатора, объявленного с помощью спецификатора класса хранения extern [File1.h] в области, в которой было объявлено Идентификатор виден [ тот, что в File2.h ], если предыдущая декларация определяет внутреннюю или внешнюю связь [, она определяет внутреннюю ], связь идентификатора в> более позднем объявлении такая же, как связь, указанная в предварительная декларация .

...