Причина, по которой указатели на неполные типы являются законными, является именно , потому что компилятору не нужно знать их размер.
Причина, по которой вы не можете объявить объект неполного типа, заключается в том, как вы упомянули, потому что компилятор не знает, насколько велик объект, и поэтому не может выделить для него место. Однако при объявлении указателя на неполный тип размер известен, поскольку обычно все указатели на машине имеют одинаковый размер.
Более того, вам не нужно знать, насколько велик объект, когда объявляет указатель на объект неполного типа. Однако, если вы попробуете , используя объект неполного типа, например, следуя этому указателю или попытавшись создать экземпляр объекта этого типа, компилятор выдаст вам ошибку.
Короче говоря, указатель допустим, потому что он может быть создан без знания компилятором размера того, на что он указывает. Однако если вам действительно нужно узнать размер или расположение этого объекта с помощью указателя, компилятору потребуется больше информации о типе.