Когда использовать статическое ключевое слово перед глобальными переменными? - PullRequest
61 голосов
/ 07 декабря 2009

Может кто-нибудь объяснить, когда предполагается использовать ключевое слово static перед глобальными переменными или константами, определенными в заголовочных файлах?

Например, допустим, у меня есть файл заголовка со строкой:

const float kGameSpriteWidth = 12.0f;

Должно ли это иметь static перед const или нет? Каковы некоторые рекомендации по использованию static?

Ответы [ 8 ]

87 голосов
/ 07 декабря 2009

Вы не должны определять глобальные переменные в заголовочных файлах. Вы должны определить их в исходном файле .c.

  • Если глобальная переменная должна быть видимой только в одном файле .c, вы должны объявить ее статической.

  • Если глобальная переменная будет использоваться в нескольких файлах .c, вы не должны объявлять ее статической. Вместо этого вы должны объявить его extern в заголовочном файле, включенном во все .c файлы, которые в нем нуждаются.

Пример:

  • example.h

    extern int global_foo;
    
  • foo.c

    #include "example.h"
    
    int global_foo = 0;
    static int local_foo = 0;
    
    int foo_function()
    {
       /* sees: global_foo and local_foo
          cannot see: local_bar  */
       return 0;
    }
    
  • bar.c

    #include "example.h"
    
    static int local_bar = 0;
    static int local_foo = 0;
    
    int bar_function()
    {
        /* sees: global_foo, local_bar */
        /* sees also local_foo, but it's not the same local_foo as in foo.c
           it's another variable which happen to have the same name.
           this function cannot access local_foo defined in foo.c
        */
        return 0;
    }
    
49 голосов
/ 07 декабря 2009

static отображает переменную local для файла, что, как правило, хорошо, см., Например, эту запись в Википедии .

21 голосов
/ 07 декабря 2009

Да, используйте статический

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

Никогда не используйте статический файл в .h файлах, поскольку вы будете создавать новый объект каждый раз, когда он включается.

8 голосов
/ 07 декабря 2009

Практическое правило для заголовочных файлов:

  • объявите переменную как extern int foo; и поместите соответствующую инициализацию в один исходный файл, чтобы получить изменяемое значение, общее для единиц перевода
  • используйте static const int foo = 42;, чтобы получить константу, которая может быть встроена
4 голосов
/ 07 декабря 2009

static перед глобальной переменной означает, что эта переменная недоступна извне модуля компиляции, где она определена.

например. представьте, что вы хотите получить доступ к переменной в другом модуле:

foo.c

int var; // a global variable that can be accessed from another module
// static int var; means that var is local to the module only.
...

bar.c

extern int var; // use the variable in foo.c
...

Теперь, если вы объявите var статичным, вы не сможете получить к нему доступ из любого места, кроме модуля, в который foo.c скомпилирован.

Обратите внимание, что модуль является текущим исходным файлом, плюс всех включенных файлов. то есть вы должны скомпилировать эти файлы отдельно, а затем связать их вместе.

3 голосов
/ 02 апреля 2016

Ключевое слово static используется в C до , ограничивая видимость функции или переменной ее единицей перевода . Единица трансляции является окончательным входом в компилятор C, из которого создается объектный файл.

Проверьте это: Связывание | Единица перевода

0 голосов
/ 07 декабря 2009

глобальные статические переменные инициализируются во время компиляции в отличие от автоматических

0 голосов
/ 07 декабря 2009

Правильный механизм для C ++ в анонимных пространствах имен. Если вам нужно что-то локальное для вашего файла, вам следует использовать анонимное пространство имен, а не статический модификатор.

...