Re: Чёртов язык Си!
yuri.nefedov@gmail.com -> debian-russian@lists.debian.org @ Tue, 7 Oct 2014 15:16:13 +0400 (MSK):
>> Фишка в том, что можно написать в заголовке:
>> ---------- point.h ----------
>> struct point;
>> struct point* point_constructor();
>> int point2number(struct point* p);
>> -----------------------------
>>
y> А, понял. Это называется предварительное объявление
y> (forward declaration). Объявление объявления )
y> Вообще говоря в С это как-то туманно описано.
y> Нет не только в K&R, но и в стандарте я не нашел
y> ничего внятного.
Тонкость в том, что это все не очень интересно, пока это именно что
forward declaration. Т.е. когда определения потом все-таки будут. В
таком виде нужно ровно для определения взаимно рекурсивных структур
данных.
А вот когда определения потом и не будет (когда оно из библиотеки наружу
не торчит) - получаются очень изрядные дополнительные плюсы.
Минус тоже есть - создание таких структур в стеке вызовов (и вообще в
памяти, управляемой вызывающей программой) становится изрядным геморроем
(работает, но с дополнительными прыжками и ужимками в API).
y> Особенно достают такие forward declaration
y> в тайпдефах. Что-то типа такого:
В таком виде - да. Впрочем, это далеко не единственный способ в C
прострелить ногу читателю твоей программы.
y> ----------------------------------------------------
y> #include <stdio.h>
y> typedef struct s s; typedef struct s* ps; typedef struct t t; typedef struct t* pt;
y> struct s{
y> int i;
y> pt pt;
y> };
y> struct t{
y> int j;
y> ps ps;
y> };
y> void print_s(ps s){
y> printf(" s= %i %p\n",s->i,s->pt);
y> }
y> void print_t(pt t){
y> printf(" t= %i %p\n",t->j,t->ps);
y> }
y> int main()
y> {
y> s s1 = {1,NULL};
y> t t1 = {2,&s1};
y> s1.pt = &t1;
y> print_s(&s1);
y> print_t(&t1);
y> return 0;
y> }
y> ----------------------------------------------
y> Это работающий пример.
y> Честно говоря книг по С, где хоть как-то это пояснялось
y> я не знаю.
Reply to: