Ответ 1
До того, как C был стандартизирован, многим компиляторам не пришлось бы работать с нулевыми типами, если бы код никогда не пытался вычитать один указатель на нулевой размер из другого. Такие типы были полезны, и поддержка их была проще и дешевле, чем их запрещать. Другие компиляторы решили запретить такие типы, однако, и некоторый код статического утверждения мог полагаться на тот факт, что они будут кричать, если код попытается создать массив нулевого размера. Авторы Стандарта столкнулись с выбором:
-
Разрешить компиляторам молча принимать объявления массивов нулевого размера, даже в случаях, когда целью таких заявлений было бы инициирование диагностики и прерывания, и требуют, чтобы все компиляторы принимали такие объявления (хотя и не обязательно молча) .
-
Разрешить компиляторам молча принимать объявления массивов нулевого размера, даже в случаях, когда целью таких заявлений было бы инициирование диагностики и прерывания, а также позволяют компиляторам встречаться с такими декларации, чтобы либо прекратить компиляцию, либо продолжить ее на досуге.
-
Требовать, чтобы реализации выдавали диагностику, если код объявляет нулевой размер массива, но затем разрешить реализации либо прервать компиляции или продолжения (с любой семантикой, которую они сочтут нужным) в их досуг.
Авторы Стандарта выбрали №3. Следовательно, объявления массивов нулевого размера рассматриваются стандартным "расширением", хотя такие конструкции широко поддерживались до того, как стандарт запретил их.
Стандарт С++ допускает существование пустых объектов, но для того, чтобы разрешить адреса пустых объектов использоваться в качестве токенов, он требует, чтобы они имели минимальный размер 1. Для объекта, у которого нет членов, поэтому размер 0 будет нарушать Стандарт. Однако, если объект содержит элементы с нулевым размером, стандарт С++ не предъявляет требований о том, как он обрабатывается, за исключением того, что программа, содержащая такое объявление, должна инициировать диагностику. Поскольку большинство кодов, которые используют такие объявления, ожидают, что результирующие объекты имеют нулевой размер, наиболее полезным поведением для компиляторов, получающих такой код, является их обработка таким образом.