Вне возможных сценариев, включающих оптимизацию всей программы, код, сгенерированный для чего-то вроде:
struct foo *bar;
struct foo *test(struct foo *whatever, int blah)
{
return blah ? whatever: bar;
}
не будет зависеть от того, что могут содержать члены struct foo
. Поскольку утилиты make обычно перекомпилируют любой модуль компиляции, в котором появляется полное определение структуры, даже когда такие изменения не могут фактически повлиять на сгенерированный для них код, часто пропускают полные определения структуры из модулей компиляции, которые на самом деле не нужны. их, и такое упущение, как правило, не заслуживает предупреждения.
Компилятор должен иметь полное определение структуры или объединения, чтобы знать, как обрабатывать объявления объектов типа с автоматической или статической продолжительностью, объявления агрегатов, содержащие члены типа, или код, который обращается к членам структуры или объединения. Если у компилятора нет информации, необходимой для выполнения одной из вышеуказанных операций, у него не будет иного выбора, кроме как кричать об этом.
Между прочим, есть еще одна ситуация, когда стандарт позволил бы компилятору требовать, чтобы полное определение объединения было видимым, но не требовал диагностики: если две структуры начинаются с общей начальной последовательности, и вид объединения, содержащий оба, является видимым когда компилятор обрабатывает код, который использует указатель одного из типов структуры для проверки члена этой общей начальной последовательности, компилятор должен распознать, что такой код может обращаться к соответствующему члену структуры другого типа. Я не знаю, какие компиляторы соответствуют стандарту, когда виден полный тип объединения, но не тогда, когда его нет [gcc склонен генерировать несоответствующий код в любом случае, если не используется флаг -fno-strict-aliasing
, в в этом случае он будет генерировать соответствующий код в обоих случаях], но если кто-то хочет написать код, который использует правило CIS таким образом, чтобы гарантировать правильное поведение на соответствующих компиляторах, может потребоваться убедиться, что полное определение типа объединения видно; Невыполнение этого требования может привести к тому, что компилятор автоматически создаст фиктивный код.