Компілятор не може розрахувати, скільки пам’яті struct s b[];
буде зайнято. Це означає, що якщо структура має будь-які поля після неї, компілятор не може зрозуміти, де ці поля.
Раніше (у старих версіях C) (наприклад) struct s b[];
не дозволялося входити до складу структури. Це робило ефективне управління пам’яттю неприємним. Для простого прикладу уявіть, що у вас є структура, що містить рядок "name" (це може бути лише кілька символів або багато з них). Ви можете використовувати масив фіксованого розміру, який є достатньо великим для найбільшого імені (що марнує простір), або скористатися покажчиком та виділити 2 частини пам'яті (одну для структури та одну для рядка імені змінної довжини). Крім того, ви можете використовувати вказівник і зробити так, щоб він вказував на додатковий простір за кінцем структури, що закінчується приблизно так:
length = strlen(my_string);
foo = malloc(sizeof(MYSTRUCTURE) + length + 1);
foo->name = (void *)foo + sizeof(MYSTRUCTURE);
memcpy(foo->name, my_string, length + 1);
Це був найефективніший варіант; але це також негарно та схильне до помилок.
Щоб обійти це, компілятори додали нестандартні розширення, щоб дозволити "масиви невідомого розміру" в кінці структури. Це трохи полегшило програмістів і зробило трохи більш ефективним (оскільки немає необхідності в додатковому члені покажчика). Врешті-решт це було прийнято стандартом С (можливо, в С99 - я не пам’ятаю).