LINUX.ORG.RU

Как разрешить круговую зависимость структур?

 


0

1
typedef void (* B)(C *);

typedef struct
{
    [..]

    B b;
} A;

typedef struct
{
    [..]

    A * a;
} C;

Уже битый час бьюсь, не могу понять, можно ли решить это нормальным способом. В C всего лишь указатель на A, поэтому скорее всего можно как-то задекларить.

★★★★★

декларировать :-)

struct A;
struct B;

typedef struct A {
  struct B *b;
} A;
typedef struct B {
  struct A *a;
} B;

MKuznetsov ★★★★★
()

Сейчас ты напишешь, что всё не подходит, потому что в параметрах функции не хочешь писать struct C.

i-rinat ★★★★★
()
typedef struct A A;
typedef struct C C;

/* используем (A *) и (C *) без struct */

struct A
{
	/* ... */
};

struct C
{
	/* ... */
};
Deleted
()

Конечно можно.

struct C;

typedef struct C C;

typedef void (*B)(C *);

struct A
{
    B b;
};

typedef struct A A;


struct C
{
    A * a;
};

fsb4000 ★★★★★
()
Ответ на: комментарий от PPP328

На самом деле тебе подошел ответ vmx’а.

anonymous
()
Ответ на: комментарий от kirk_johnson

Нет если мозга хватает добавлять постфикс _st. Также для union _ut. А вообще да, тупедефать удобно только в локальном пространстве, типа функций что бы там монстры вида settings_data_st[settings_data_st.data_counter].enable_someone = true; превращать на время во что-то более короткое.

Deleted
()
Ответ на: комментарий от PPP328

Если это внутренняя хрень которую видишь только ты то да надо тупедефать, если это функция во вне надо либо писать struct либо тупедефать, но с приставкой в имени иначе откуда хрен узнаешь структура передаётся в функцию или объединение.

Deleted
()
Ответ на: комментарий от Deleted

иначе откуда хрен узнаешь структура передаётся в функцию или объединение.

А это не нужно знать на этапе написания. Если вы бездумно пихаете везде поинтеры вперемешку на структуры и объединения не смотря на ТИП в декларации - то вон из профессии. Вам должно быть по-барабану юнион там, структура или инт под капотом от (ffg_mutex_t). Если функция требует ffg_mutex_t, то его надо туда запихнуть.

PPP328 ★★★★★
() автор топика
Ответ на: комментарий от PPP328

Еще один любитель писать struct во всех функциях и объявлении переменных.
https://stackoverflow.com/a/612350/2932207

А вы точно указанный URL прочли?

struct foo { int a; } s1;

int foo()
{
        return s1.a;
}

typedef struct bar { int a; } bar;
bar s2;

/* error ! */
int bar()
{
        return s2.a;
}

int main(void)
{
        return foo() + bar();
}

vodz ★★★★★
()
Ответ на: комментарий от vodz
int stat(const char *pathname, struct stat *buf);

То что это обычная практика не значит что так НАДО делать. Все типы в std имеют постфикс _t (time_t, mutex_t и пр). Тут на это забили и получили геморрой с читаемостью и объявленной структурой.

PPP328 ★★★★★
() автор топика
Ответ на: комментарий от PPP328

То что это обычная практика

Именно так. Оно и старше вас и вас переживёт. Так как там нет никакой проблемы, кроме вашего инфантильного нигилизма не по делу.

vodz ★★★★★
()
Ответ на: комментарий от vodz

Оно и старше вас и вас переживёт.

Кудах-кудах, кто-то когда-то поел говна,давайте теперь все бездумно есть говно. Я вам уже показал, почему то что они сделали - говно, нарушающее их же правила нейминга.

PPP328 ★★★★★
() автор топика
Ответ на: комментарий от PPP328

А это не нужно знать на этапе написания.

В смыслеееее.

Не знаю как в твоей вселенной, а я сначала декларирую структуры и объединения, а затем пишу обрабатывающие их функции. Что ты имел в виду под словами «ненужно знать»?

Если вы бездумно пихаете везде поинтеры вперемешку на структуры и объединения не смотря на ТИП в декларации - то вон из профессии.

Дык я к тому что не надо тупедефать именно до декларации, что бы в объявляемой функции было чётко приписано function(struct mystruct st); а не сразу тупедефное значение. И чё сразу бездумно, где то нужна обработка по указателю, а где то по значению.

Вам должно быть по-барабану юнион там, структура или инт под капотом

Нет, нам должно быть чётко ясно с каким типом мы работаем, если у меня есть структура timespec я не должен думать что это объединение.

Если функция требует ffg_mutex_t, то его надо туда запихнуть.

Естественно, она тупо ничего другого не примет )))), но надо понимать что ты передаёшь, ладно там есть curl, который просто аля объект гуляет по обрабатывающим функциям, но с конечными структурами надо работать же, я не хочу передавать в функцию 20 значений я создам структуру которую буду туда передавать данные через неё и функция мне вернёт структуру с другими данными, я ДОЛЖЕН знать что я передаю и что мне передают.

Deleted
()
Ответ на: комментарий от PPP328

кто-то когда-то поел говна

Тю. Вот как научите в Как разрешить круговую зависимость структур? (комментарий) даже не компилиться, а просто хотя бы подсвечивать «bar» (это же теперь модно-молодёжно, значить можете), так приходите, поговорим уже о синтаксисе и области видимости.

vodz ★★★★★
()
Ответ на: комментарий от ox55ff

В смысле мусор? Строгая декларация и чёткое понимание типа данных. Это у скриптоты на всё провсё var/let и усё.

Deleted
()
Ответ на: комментарий от Deleted

Нет, нам должно быть чётко ясно с каким типом мы работаем, если у меня есть структура timespec я не должен думать что это объединение.

Но какая вам разница? Вот до появления IPv6 всё что работало с IP было структурами, а теперь всё стало union. И ничего особого не изменилось, надо просто af/socklen правильный задавать, теперь оно не прощает неверные.

vodz ★★★★★
()
Ответ на: комментарий от Deleted

Я не предлагаю опускаться до скриптоты. Но это чрезмерное обмазывание ключевыми словами там, где компилятор может догадаться сам. В крестах же живут как-то и не пишут struct в объявлениях аргументов функций.

ox55ff ★★★★★
()
Ответ на: комментарий от vodz

Я имел в виду когда мы сами что-то реализуем. Или копаемся в кишках чего либо. Если говорить про API то да часто не важно функция нам создала тип мы этот тип передали другой функции и всё, тут да бывает и не важно что внутри. Но я не про это говорил )) Так что всё нормально.

Deleted
()
Ответ на: комментарий от Deleted

Да боже мой. Вся разница в struct и union - это общую или последовательную память будут занимать члены. Ничего другого там нет. Ни синтаксически, ни интерфейсно. Никак. Зачем вам знать сколько будет размер пакета IP, если вы RAW пакеты заколебётесь формировать, да еще только от рута?

vodz ★★★★★
()
Ответ на: комментарий от ox55ff

Ну что бы не писать struct есть typedef, есть выбор хоть так пиши, хоть сяк, хоть вообще для всего сделать тип var и не парится вообще можно, можно всё, только вот есть разница пишем ли мы код для стиральной машинки или обычного пк. Да и в целом уж прям не беда слово написать чётко определяющее что у тебя перед глазами. Написать секунда, прочитать не больше, зато наглядность.

Deleted
()
Ответ на: комментарий от vodz

Зачем вам знать

Я не говорю что всегда надо знать, но это не отменяет того что знать не надо. Сам код обработки пакетов же люди пишут и им надо знать )) Я не говорю про прикладную область, я говорю в целом.

Вся разница в struct и union - это общую или последовательную память будут занимать члены. Ничего другого там нет. Ни синтаксически, ни интерфейсно.

И что?

Зачем вам знать сколько будет размер пакета IP

Ну захочу я свой дампер делать, память мне выделять из sizeof(libastral)?

Deleted
()
Ответ на: комментарий от PPP328

то вон из профессии

Всё нормально я не программист и не в профессии ))

Deleted
()
Ответ на: комментарий от Deleted

Зачем мне знать, что это структура, а не объединение, перечисление или целое? Я считаю это излишним.

ox55ff ★★★★★
()
Ответ на: комментарий от Deleted

Ну захочу я свой дампер делать, память мне выделять из sizeof(libastral)?

Угу, примерно так. Вам придётся узнать размер заголовка всех возможных в этом интерфейсе типов пакетов, и прибавить mru интерфейса. Вот на моей памяти когда то у lo mtu был 32k, сейчас вот (честно-честно, совсем недавно обратил внимание, нафиг не надо было) оказывается 64k.

vodz ★★★★★
()
Ответ на: комментарий от vodz

Вам придётся узнать размер заголовка всех возможных в этом интерфейсе типов пакетов

Ну если придётся то придётся ))) Я уже раз третий повторяю что не обязательно, но там где нужно там нужно и не надо гадать будет и в этом случае банально удобнее для восприятия знать что это вот, структура, а это вот объединение. Всё это лишь вопрос восприятия и читаемости.

Deleted
()
Ответ на: комментарий от ox55ff

Зачем мне знать, что это структура, а не объединение, перечисление или целое? Я считаю это излишним.

Если ты не причастен к заданию им значений то да. Значит это просто служебный тип обрабатываемый полностью внутренностями для служебных нужд. Как в банальныном FILE * pfile = fopen("./txt",«r»); нам не важно что такое pfile в итоге.

Deleted
()
Ответ на: комментарий от Deleted

Если ты не причастен к заданию им значений то да.

Если мне нужно будет установить/прочитать значение внутри типа, то я всё равно полезу в документацию/автодополнение и узнаю что это за тип: структура или ещё что-то. Сам факт осознания, что аргумент это структура мало что даёт. Но это моё ИМХО.

ox55ff ★★★★★
()
Ответ на: комментарий от kirk_johnson

Понятия не имею, меня не заставляет.

Но если не сделать typedef на структуру, то при определении аргументов функций придётся писать ключевое слово struct перед типом. Или ты собираешь через g++?

ox55ff ★★★★★
()
Ответ на: комментарий от kirk_johnson

дело же не в скорости печати, а в том что потом весь этот ненужный мусор придётся читать

anonymous
()
Ответ на: комментарий от kirk_johnson

- У вас тут гвоздь из стула торчит
- Ничего не знаю, мне удобно. А тех, кто торчащие гвозди из стула убирает нужно по пальцам бить

Aswed ★★★★★
()
Ответ на: комментарий от ox55ff

Но если не сделать typedef на структуру, то при определении аргументов функций придётся писать ключевое слово struct перед типом.

Да, это действительно важное преимущество.

Deleted
()
Ответ на: комментарий от kirk_johnson
EXPORT sml_error sml_widget_init            (sml_widget * wid, bxi_point * pos, bxi_size * size);
EXPORT sml_error sml_widget_free            (sml_widget * wid);

EXPORT sml_error sml_widget_visible_set     (sml_widget * wid, bool   show);
EXPORT sml_error sml_widget_visible_get     (sml_widget * wid, bool * show);
EXPORT sml_error sml_widget_togglable_set   (sml_widget * wid, bool   tog);
EXPORT sml_error sml_widget_togglable_get   (sml_widget * wid, bool * tog);
EXPORT sml_error sml_widget_focusable_set   (sml_widget * wid, bool   foc);
EXPORT sml_error sml_widget_focusable_get   (sml_widget * wid, bool * foc);
EXPORT sml_error sml_widget_is_neutral      (sml_widget * wid, bool * val);
EXPORT sml_error sml_widget_is_hover        (sml_widget * wid, bool * val);
EXPORT sml_error sml_widget_is_pressed      (sml_widget * wid, bool * val);
EXPORT sml_error sml_widget_is_focused      (sml_widget * wid, bool * val);
EXPORT sml_error sml_widget_is_disabled     (sml_widget * wid, bool * val);
EXPORT sml_error sml_widget_is_checked      (sml_widget * wid, bool * val);
EXPORT sml_error sml_widget_size_set        (sml_widget * wid, bxi_size * size);
EXPORT sml_error sml_widget_size_get        (sml_widget * wid, bxi_size * size);
EXPORT sml_error sml_widget_pos_set         (sml_widget * wid, bxi_point * pos);
EXPORT sml_error sml_widget_pos_get         (sml_widget * wid, bxi_point * pos);
EXPORT sml_error sml_widget_title_set       (sml_widget * wid, char  * title);
EXPORT sml_error sml_widget_title_get       (sml_widget * wid, char ** title);
EXPORT sml_error sml_widget_x_window_get    (sml_widget * wid, Window * window);
EXPORT sml_error sml_widget_x_mask_get      (sml_widget * wid, u32 * mask);
EXPORT sml_error sml_widget_parent_get      (sml_widget * wid, sml_widget ** par);
EXPORT sml_error sml_widget_parent_set      (sml_widget * wid, sml_widget *  par);
EXPORT sml_error sml_widget_child_get       (sml_widget * wid, sml_widget ** chl);
EXPORT sml_error sml_widget_child_foc_get   (sml_widget * wid, sml_widget ** chl);
EXPORT sml_error sml_widget_next_get        (sml_widget * wid, sml_widget ** rel);
EXPORT sml_error sml_widget_prev_get        (sml_widget * wid, sml_widget ** rel);
EXPORT sml_error sml_widget_swap_order_left (sml_widget * wid);
EXPORT sml_error sml_widget_swap_order_right(sml_widget * wid);
EXPORT sml_error sml_widget_cb_get          (sml_widget * wid, sml_event event, sml_event_type type, sml_event_cb * func);
EXPORT sml_error sml_widget_cb_set          (sml_widget * wid, sml_event event, sml_event_type type, sml_event_cb   func);
EXPORT sml_error sml_widget_cb_rem          (sml_widget * wid, sml_event event, sml_event_type type);

Сколько буковок я должен тут написать? Шесть? А может двести?

PPP328 ★★★★★
() автор топика
Ответ на: комментарий от kirk_johnson

Я сравнил твою позицию с сидением на гвозде. Потому как тебе человек говорит: «Ну вот есть недостаток, кому-то неудобно. Зачем это?». А ты такой: «Ничего не вижу, ничего не знаю, всегда так делал и ты делай».

Aswed ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.