
最近看 wpa_supplicant 的代码,发现有许多的结构体都相互嵌套
什么情况下我们会选择这种相互嵌套的结构?
例如下面的 wpa_supplicant 和 wpa_global
exp:
struct wpa_supplicant { struct wpa_global *global; struct wpa_radio *radio; /* shared radio context */ structdl_list radio_list; /* list head: struct wpa_radio::ifaces */ struct wpa_supplicant *parent; struct wpa_supplicant *p2pdev; struct wpa_supplicant *next; struct l2_packet_data *l2; struct l2_packet_data *l2_br; unsigned char own_addr[ETH_ALEN]; unsigned char perm_addr[ETH_ALEN]; char ifname[100]; ... struct wpa_global { struct wpa_supplicant *ifaces; struct wpa_params params; struct ctrl_iface_global_priv *ctrl_iface; struct wpas_dbus_priv *dbus; struct wpas_binder_priv *binder; void **drv_priv; size_t drv_count; struct os_time suspend_time; struct p2p_data *p2p; struct wpa_supplicant *p2p_init_wpa_s; struct wpa_supplicant *p2p_group_formation; struct wpa_supplicant *p2p_invite_group; ... 1 wizardoz 2019 年 1 月 10 日 这个不叫嵌套好吧,顶多算是一种关联。 |
2 wizardoz 2019 年 1 月 10 日 就好比双向链表,a 的 next 指向 b,b 的 prev 指向 a。你不能说它是相互嵌套啊 |
3 jagger2048 2019 年 1 月 10 日 相互嵌套 谈不上,用个结构体封装其他结构体指针,可以比较方便地管理资源,如果是 C++可以用类的某些特性(派生继承多态)来封装 |
4 aijam 2019 年 1 月 10 日 爹认识儿子,儿子也要认识爹。 |
5 zn 2019 年 1 月 10 日 这个叫互相引用,不叫互相嵌套。 |
6 GeruzoniAnsasu 2019 年 1 月 10 日 这是个每个节点都带有指向根节点指针的树结构 |
7 wutiantong 2019 年 1 月 10 日 99%的 C 语言项目都能看到这种“相互嵌套”,题主一定是没用 C 语言做过工程实践。 |
8 dazhangpan 2019 年 1 月 10 日 有点就是互相都知道地址,去谁家串个门都方便 |
9 liuxey 2019 年 1 月 10 日 互相引用这种事情别说 C,Java 里也很常见嘛,还记得一对多和多对多吗 |
10 reus 2019 年 1 月 10 日 那是指针,存的是指针,没有嵌套 真的嵌套的话,是编译不过的,因为结构体大小是无限大,没法编译 |
11 flyingghost 2019 年 1 月 10 日 相互嵌套。。。吓我一大跳,申请一个实例直接就爆内存了啊喂! 只是互相关联,互相存一个指针而已。莫慌,莫慌。 |
12 FrankHB 2019 年 1 月 10 日 看起来是作者水平比较屎,因为无知或盲信 Linux Kernel Coding Style 5)之类的反智胡扯,不知道用显式类型体现更明确的目的(考虑到下面的 magic,前者跑不掉)。换 C 艹可能就被打死了。 真正互相引用的像链表的 prev/next 的情况理应是非常少的,并且基本可以且往往应该排除出业务代码。 然后看了下代码(主要是 wpa_supplicant_deinit_iface ),果然是属于混用所有权和链表访问的需要被打死的情况。在我这边 review 避免被打死的标准套路起手( C 艹版本)是 wpa_supplicant *ifaces 改成 pmr::list<wpa_supplicant> ifaces,struct wpa_global *global 改成 observer_ptr<wpa_global>。C 嘛要考虑的细节麻烦多了(……比如避免_t 踩到 POSIX reserve name ),懒得示范了。 |
13 FrankHB 2019 年 1 月 10 日 贴漏了,observer_ptr<wpa_global>后补 global。另外看起来是内部用的,不管 ABI compat 直接改 pmr::forward_list 好了,更接近原逻辑。 @jagger2048 知道是 C 代码就别拿 C 艹的习惯说大话了,看看实际代码就知道不符合你这里说的任何一种情况(尽管看的确实是“资源管理”有点关系的代码)。 |
14 Persona0x4343 OP @GeruzoniAnsasu 谢谢,我数据结构就了解到链表那里,会去补一下相关知识 |