Некоторые практические правила:
- Никогда не объявляйте глобальные переменные. (
extern
единицы) - Никогда не объявляйте переменные внутри заголовочных файлов.
static
переменные по определению не являются глобальными, но могут быть «областью действия файла», то есть видимой в файл они объявлены внутри. Точнее, видимые внутри единицы перевода они объявлены внутри, единица перевода означает конкретный файл c. c и все заголовки, которые включает в себя c файл.
Таким образом, если вы объявляете переменную static
в заголовке, который включается в два разных файла. c, вы получаете несколько локальных копий переменной. Если вам повезет, вы получите ошибку компоновщика, но компоновщик также может попытаться выполнить какое-то внутреннее «искажение имени». Само значение static
состоит в том, чтобы запретить доступ к переменной другим файлам.
Лучшее решение для этого - использовать функции установки / получения:
// abc.h
#ifndef ABC_H // always use "header guards"
#define ABC_H
uint8_t get_a (void);
void set_a (uint8_t n);
#endif
-
// abc.c
#include "abc.h"
static uint8_t a;
uint8_t get_a (void)
{
return a;
}
void set_a (uint8_t n)
{
a = n;
}
Именно так вы должны поступить в подавляющем большинстве случаев. Следует избегать использования extern
, но в тех редких случаях, когда вам нужно его использовать, используйте его следующим образом:
// abc.h
#ifndef ABC_H // always use "header guards"
#define ABC_H
extern uint8_t a;
#endif
-
// abc.c
#include "abc.h"
uint8_t a;