В ответ на другой вопрос я наткнулся на такой код, который gcc компилирует без жалоб.
typedef struct {
struct xyz *z;
} xyz;
int main (void) {
return 0;
}
Это средство, которое я всегда использовал для создания типов, которые указывают на себя (например, связанные списки), но я всегда думал, что вам нужно назвать структуру, чтобы вы могли использовать самоссылку , Другими словами, вы не можете использовать xyz *z
внутри структуры, потому что typedef еще не завершен.
Но этот конкретный образец не называет структуру, и он все еще компилируется. Первоначально я думал, что в компиляторе происходит какая-то черная магия, которая автоматически переводит приведенный выше код, потому что имена структур и typedef совпадают.
Но эта маленькая красавица тоже работает:
typedef struct {
struct NOTHING_LIKE_xyz *z;
} xyz;
Что мне здесь не хватает? Это выглядит явным нарушением, поскольку нигде не определен тип struct NOTHING_LIKE_xyz
.
Когда я меняю указатель на фактический тип, я получаю ожидаемую ошибку:
typedef struct {
struct NOTHING_LIKE_xyz z;
} xyz;
qqq.c:2: error: field `z' has incomplete type
Кроме того, когда я удаляю struct
, я получаю сообщение об ошибке (parse error before "NOTHING ...
).
Это разрешено в ISO C?
Обновление: struct NOSUCHTYPE *variable;
также компилируется, так что это не просто внутри структур, где оно кажется допустимым. Я не могу найти ничего в стандарте c99, который позволял бы эту снисходительность для указателей структуры.