Ответ 1
gcc правильный, но clang не требуется для диагностики (3.3.7):
Имя N, используемое в классе S, должно ссылаться на одно и то же объявление в его контекста и при повторной оценке в завершенном объеме С. Нет для нарушения этого правила требуется диагностика.
Это связано с тем, как работает область видимости класса. foo
of void foo();
отображается внутри области целиком класса A
, поэтому декларация void foo();
изменяет значение foo
в typedef, ссылаясь на struct foo
к имени функции foo
.