Вы ошибочно предположили, что ваша вторая структура «вызывает» первую. Это не так.
В действительности первая декларация структуры объявляется как untagged тип структуры с псевдонимом typedef struct_one
. Единственный способ обратиться к этому типу - struct_one
. Только struct_one
, а не struct struct_one
.
Вторая декларация структуры объявляет struct struct_two
, что относится к типу struct struct_one
. Этот последний тип не имеет абсолютно никакого отношения к ранее объявленному типу struct_one
: struct struct_one
и struct_one
- это два совершенно разных, несвязанных типа. Ваша ссылка на struct struct_one
внутри второй структуры рассматривается как введение, a декларация совершенно нового типа struct struct_one
. Компилятор предполагает, что вы позже определите этот тип (при необходимости).
Поскольку вы ничего не делаете в своем коде, вы не сталкиваетесь с какими-либо проблемами, вызванными такой ошибкой. В качестве дополнительной иллюстрации того, что может произойти, следующий пример
int main(void) {
struct_one *p = 0;
struct struct_two s2;
s2.ptr = p;
return 0;
}
Этот код будет немедленно произвести диагностическое сообщение от компилятора, поскольку s2.ptr = p;
присвоение является незаконным: типы указателей не имеют никакого отношения. Указатель левой стороны - struct struct_one *
, а указатель справа - struct_one *
.
Еще раз, в языке C при использовании struct <something>
синтаксиса в контекстах, которые не требуют полного типа, вы можете написать практически все, что вместо <something>
: полного бреда (до тех пор, как это лексический действительный идентификатор). Если тип еще не известен, компилятор просто предположит, что вы вводите новый тип, например.
int main() {
struct klshcjkzdcdsamcbsj78q43698 *p = 0;
}
Вышеупомянутая версия является полностью действующей программой C.
Вы неявным образом объявляете тип 'struct struct_one' при объявлении указателя на тот же. Если вы хотите увидеть, как это происходит, попробуйте 'struct two obj; obj.ptr = malloc (sizeof * obj.ptr); 'в' main() ', тем самым выдавая [существенное сомнение] (http://ideone.com/4fcdXF) на« этот работает! ». – WhozCraig
Вот почему я не согласен с «общей» (?) Мудростью, чтобы не печатать ваши структуры. Опечатка в имени typedef попадает в компилятор, но опечатка в теге struct может отсутствовать, в зависимости от того, как она используется. –