Оба должны скомпилироваться.
И int i;
, и static int i;
являются предварительными определениями в C, поскольку они не имеют инициализатора и не extern
. Вам разрешено несколько предварительных объявлений и самое большее одно не предварительное определение для любого объекта в единице перевода, если определения не конфликтуют в типе или связи.
ИСО / МЭК 9899: 1999 6.9.2:
Объявление идентификатора для объекта, который имеет область файла без инициализатора и без спецификатора класса хранения или со спецификатором класса хранения static
, составляет предварительное определение . Если модуль перевода содержит одно или несколько предварительных определений для идентификатора, а модуль перевода не содержит внешних определений для этого идентификатора, то поведение точно такое, как если бы модуль перевода содержал объявление области файла этого идентификатора с составным типом как конца блока перевода, с инициализатором, равным 0.