static int Sw_Type [];
составляет предварительное определение , согласно C 2018 6.9.2 2:
Объявление идентификатора для объекта, который имеет область действия файла без инициализатора,и без спецификатора класса хранения или со спецификатором класса хранения static составляет предварительное определение .Если модуль перевода содержит одно или несколько предварительных определений для идентификатора, а модуль перевода не содержит внешнего определения для этого идентификатора, то поведение точно такое, как если бы модуль перевода содержал объявление области файла для этого идентификатора с составным типом какконца единицы перевода, с инициализатором, равным 0.
Поскольку ваша программа не дает неумышленного определения, она выглядит так, как если бы она заканчивалась на static int Sw_Type [] = { 0 };
.(Если из приведенного выше текста не ясно, что результат действительно является массивом из одного элемента, это становится понятным из Примера 2 в параграфе 5 того же пункта.)
Таким образом, Sw_Type
массив из одного int
.Он содержит только элемент Sw_Type[0]
.Поведение доступа к Sw_Type[1]
не определено стандартом C.Из наблюдений, о которых вы сообщаете, кажется, что Sw_Update
следует за Sw_Type
в памяти, а доступ к Sw_Type[1]
приводит к изменению Sw_Update
.Это поведение, конечно, ненадежно.
Чтобы увеличить Sw_Type
, вы должны объявить размер для него, как в static int Sw_Type[4];
.
Примечание: 6.9.2 3 говорит: «Еслиобъявление идентификатора для объекта является предварительным определением и имеет внутреннюю связь, объявленный тип не должен быть неполным типом ». Хотя это может читаться как применение к объявленному типу в каждом объявлении, которое является предварительным определением, я думаю,он может быть предназначен для применения к объявленному типу объекта, как только его составной тип полностью разрешен в конце модуля перевода.Экспериментально Clang в порядке с принятием неполного типа сначала и завершением его позже.