спецификатор класса хранения stati c с глобальными данными - PullRequest
1 голос
/ 26 апреля 2020

Я читаю книгу C -Праймер Плюс. Ниже приведен текст, который я хотел бы лучше понять -

file - constant.h

/* constant.h -- defines some global constants */
static const double PI = 3.14159;
static const char * MONTHS[12] = 
       {"January", "February", "March", "April", "May", "June", "July", "August", 
        "September", "October", "November", "December"};

file - file1. c

/* file1.c -- use global constants defined elsewhere
#include "constant.h"

файл - файл2. c

/* file2.c -- use global constants defined elsewhere
#include "constant.h"

Если вы не используете ключевое слово static, включая константу .h в file1. c и в file2. c приведет к тому, что каждый файл будет иметь определяющее объявление того же идентификатора, который не поддерживается C стандарт. Делая каждый идентификатор stati c external, вы фактически предоставляете каждому файлу отдельную копию данных.

Может кто-нибудь объяснить мне вышеизложенное, чтобы я мог лучше понять это?

1 Ответ

1 голос
/ 26 апреля 2020

Если удалить спецификатор хранилища stati c наподобие

/* constant.h -- defines some global constants */
const double PI = 3.14159;
const char * MONTHS[12] = 
       {"January", "February", "March", "April", "May", "June", "July", "August", 
        "September", "October", "November", "December"};

, то в каждой единице перевода, в которую включен заголовок, будут объекты PI и MONTHS с внешней связью.

То есть единицы перевода для файла file1.c и file2.c будут иметь определения вышеуказанных объектов с внешней связью.

Теперь компоновщик не будет знать, какое определение выбрать, поскольку у него будет два определения: те же имена.

При использовании спецификатора хранения stati c эти объявления с областью действия файла не видны за пределами единиц перевода. У них есть внутренняя связь. Каждое подразделение перевода будет иметь собственное определение объектов. Так что не будет двусмысленности между определениями.

...