#c #gcc #compilation #clang #warnings
#c #gcc #Сборник #clang #предупреждения
Вопрос:
Если бы я это сделал
#include <stdio.h>
int a; //definition
int a; //definition
int a; //definition
int a; //definition
int a; //definition
int main() {
return 0;
}
Например, я бы не получил никаких ошибок или предупреждений ни от gcc, ни от clang, несмотря на многократное определение переменной. Почему? Я думал, что мне разрешено объявлять переменную столько раз, сколько я хотел, но мог определить ее только один раз?
Ответ №1:
Это предварительное определение. То есть каждое объявление переменной области видимости файла без инициализатора рассматривается как объявление, а не как определение. Определение неявно генерируется в конце единицы преобразования с инициализатором, равным 0.
Из стандарта C (6.9.2 Определения внешних объектов)
2 Объявление идентификатора для объекта, имеющего область действия файла, без инициализатора и без спецификатора класса хранения или со статическим спецификатором класса хранения, представляет собой предварительное определение. Если единица перевода содержит одно или несколько предварительных определений для идентификатора, а единица перевода не содержит внешнего определения для этого идентификатора, то поведение будет точно таким же, как если бы единица перевода содержала объявление области действия этого идентификатора с составным типом на конец единицы перевода, синициализатор равен 0.
Комментарии:
1. Это объясняет, почему он не генерирует ошибку, но предупреждение все равно может быть уместным. Это потому, что обычно используется несколько предварительных определений из разных заголовочных файлов?
2. @Barmar Я думаю, что у компилятора может быть опция, которая устанавливает предупреждение. Например, для нескольких объявлений функций некоторые компиляторы по умолчанию выдают предупреждение.
3. Я попробовал
-Weverything
на своем Mac, он не предупредил об этом.4. @Barmar Похоже, что разработчики компиляторов не считают, что это требуется. 🙂
5. Очевидно, что, хотя это кажется очевидным, о чем нужно предупреждать, если нет веской причины не делать этого.