Persona0x4343
V2EX  ›  C

C 语言中结构体相互嵌套有什么优点吗

  •  
  •   Persona0x4343 · Jan 10, 2019 · 5844 views
    This topic created in 2864 days ago, the information mentioned may be changed or developed.

    最近看 wpa_supplicant 的代码,发现有许多的结构体都相互嵌套

    什么情况下我们会选择这种相互嵌套的结构?

    例如下面的 wpa_supplicant 和 wpa_global

    exp:

    struct wpa_supplicant {
        struct wpa_global *global;
        struct wpa_radio *radio; /* shared radio context */
        struct dl_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;
    ...
    
    14 replies  •  2019-01-11 08:13:12 +08:00
    wizardoz
    wizardoz
    Jan 10, 2019
    1
    这个不叫嵌套好吧,顶多算是一种关联。
    wizardoz
    wizardoz
    Jan 10, 2019❤️2
    2
    就好比双向链表,a 的 next 指向 b,b 的 prev 指向 a。你不能说它是相互嵌套啊
    jagger2048
    jagger2048
    Jan 10, 2019❤️2
    3
    相互嵌套 谈不上,用个结构体封装其他结构体指针,可以比较方便地管理资源,如果是 C++可以用类的某些特性(派生继承多态)来封装
    aijam
    aijam
    Jan 10, 2019
    4
    爹认识儿子,儿子也要认识爹。
    zn
    zn
    Jan 10, 2019
    5
    这个叫互相引用,不叫互相嵌套。
    GeruzoniAnsasu
    GeruzoniAnsasu
    Jan 10, 2019❤️1
    6
    这是个每个节点都带有指向根节点指针的树结构
    wutiantong
    wutiantong
    Jan 10, 2019
    7
    99%的 C 语言项目都能看到这种“相互嵌套”,题主一定是没用 C 语言做过工程实践。
    dazhangpan
    dazhangpan
    Jan 10, 2019
    8
    有点就是互相都知道地址,去谁家串个门都方便
    auin
    auin
    Jan 10, 2019
    9
    互相引用这种事情别说 C,Java 里也很常见嘛,还记得一对多和多对多吗
    reus
    reus
    Jan 10, 2019
    10
    那是指针,存的是指针,没有嵌套

    真的嵌套的话,是编译不过的,因为结构体大小是无限大,没法编译
    flyingghost
    flyingghost
    Jan 10, 2019
    11
    相互嵌套。。。吓我一大跳,申请一个实例直接就爆内存了啊喂!

    只是互相关联,互相存一个指针而已。莫慌,莫慌。
    FrankHB
    FrankHB
    Jan 10, 2019❤️1
    12
    看起来是作者水平比较屎,因为无知或盲信 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 ),懒得示范了。
    FrankHB
    FrankHB
    Jan 10, 2019
    13
    贴漏了,observer_ptr<wpa_global>后补 global。另外看起来是内部用的,不管 ABI compat 直接改 pmr::forward_list 好了,更接近原逻辑。

    @jagger2048 知道是 C 代码就别拿 C 艹的习惯说大话了,看看实际代码就知道不符合你这里说的任何一种情况(尽管看的确实是“资源管理”有点关系的代码)。
    Persona0x4343
    Persona0x4343
    OP
    Jan 11, 2019
    14
    @GeruzoniAnsasu 谢谢,我数据结构就了解到链表那里,会去补一下相关知识
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2103 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 51ms · UTC 11:23 · PVG 19:23 · LAX 03:23 · JFK 06:23
    ♥ Do have faith in what you're doing.