Страницы

Поиск по вопросам

среда, 5 февраля 2020 г.

Глобальная константная переменная

#c


Нужно объявить глобальную переменную:

extern int SIZE_A=10;


Почему-то выводит предупреждение: 


warning: 'SIZE_A' initialized and declared 'extern'


    


Ответы

Ответ 1



Эта переменная у вас вовсе не константная :), но проблема не в этом. Просто нормальная практика такова: в одном файле глобальная переменная объявлена и определена, типа int SIZE_A = 10; а в других (например, с помощью механизма включаемых заголовочных файлов) - только объявлено, что где-то в другом файле (т.е. extern) есть такая переменная extern int SIZE_A; Просто иначе вы рискуете указать разные значения этой переменной в разных файлах - о чем вас и предупреждают. При этом возможны варианты, в зависимости от компилятора, когда extern со значением приведет к созданию переменной в объектном файле - тогда при линковке будет коллизия - две переменные с одинаковыми именами; какую из них считать верной? или когда extern приведет все же только к ссылке на переменную в другом файле - но тогда будет полностью проигнорировано значение в объявлении extern - его просто некуда будет записать :)

Ответ 2



В c объявление идентификатора объекта в области видимости файла, содержащее при этом инициализатор, является внешним определением (external definition) идентификатора. Если инициализатора нет, и спецификатор класса хранения static или отсутствует, то это является т.н. предварительным определением (tentative definition). Внутри единицы трансляции может быть несколько предварительных определений для одного идентификатора. Приведу пример из Стандарта C11 (6.9.2/4): int i1 = 1; //определение, внешняя компоновка static int i2 = 2; //определение, внутренняя компоновка extern int i3 = 3; //определение, внешняя компоновка int i4; //предварительное определение, внешняя компоновка static int i5; //предварительное определение, внутренняя компоновка int i1; //предварительное определение, ссылается на предыдущий int i2; //ошибка, не совпадает компоновка int i3; //предварительное определение, ссылается на предыдущий int i4; //предварительное определение, ссылается на предыдущий int i5; //ошибка, не совпадает компоновка extern int i1; //ссылается на предыдущий с внешней компоновкой extern int i2; //ссылается на предыдущий с внутренней компоновкой extern int i3; //ссылается на предыдущий с внешней компоновкой extern int i4; //ссылается на предыдущий с внешней компоновкой extern int i5; //ссылается на предыдущий с внутренней компоновкой Т.е. в Вашем случае (переменная, доступная в разных единицах трансляции) наличие явного extern необязательно. А предупреждение выводится для того, чтобы не было ложного ощущения (из-за наличия extern), что данная запись является всего лишь объявлением. Хотя на самом деле это определение (из-за наличия инициализатора). Для закрепления факта константности дополнительно следует добавить const. В итоге получим: const int SIZE_A = 10;

Ответ 3



Но ведь в сообщении написано, чёрным по английски: инициализация ВНЕШНЕЙ переменной. Если Вы сами объявили, что данная переменная НЕ Ваша (т.е. она объявлена в другом месте и кем-то другим), то какое Вы имеете право её инициализировать ?! Можно инициализировать чужую жену ? :-)

Комментариев нет:

Отправить комментарий