【问题标题】:Is it possible to get pointer to the 'this' structure, when using designated initializer?使用指定的初始化程序时,是否可以获得指向“this”结构的指针?
【发布时间】:2011-08-23 13:42:54
【问题描述】:

这种结构体作为链表的头部:

struct lista
{
    struct lista* next;
    struct lista* prev;
};

当 next 和 prev 都指向 struct 本身时,列表为空。 以下宏可用于初始化结构:

#define LISTA_INIT_EMPTY(list) { .next = (list), .prev = (list) }

这样:

struct lista my_list = LISTA_INIT_EMPTY(&my_list);

但是,有没有办法通过以下方式做同样的事情,没有宏参数?:

struct lista my_list = LISTA_INIT_EMPTY;

我尝试了以下,但它导致了编译错误:

#define LISTA_INIT_EMPTY     { .next = &.next, .prev = &.next }

【问题讨论】:

    标签: c initialization designated-initializer


    【解决方案1】:

    好吧,我看到的唯一方式就是不愉快:

    #define LISTA_INIT_EMPTY     { .next = (&my_list), .prev = (&my_list) }
    

    一点都不好,因为它仅在您的变量被称为my_list 时才有效。而且没有什么好的方法,因为 C 中不存在 this

    为什么不使用NULL 而不是指向“this”?如果这不令人满意,保留参数化宏可能是最好的。

    编辑:(感谢 R 在下面的评论,我终于明白了需要):

    由于没有“this”并且只输入一次变量名,我建议使用这样的宏:

    #define CREATE_EMPTY_LISTA(name) struct lista name = { .next=&name, .prev=&name }
    

    以及后面的代码:

    CREATE_EMPTY_LISTA(my_list); // creates and initializez my_list at the same time
    

    【讨论】:

    • 我认为 OP 希望所有列表,包括最初的空列表,都是循环的。这并非完全不合理;通常它会消除列表处理函数中所有丑陋的极端情况。
    • CREATE_EMPTY_LISTA与OP提到的LISTA_INIT_EMPTY基本相同。
    • 是的,但有一个重要区别:struct lista my_list = LISTA_INIT_EMPTY(&my_list); 强制您重复变量的名称,这不是很好而且很容易出错。 CREATE_EMPTY_LISTA(my_list); 让你不再重复。
    【解决方案2】:

    请注意,您的列表初始化技术与 Linux 内核源代码中用于链接列表 (include/linux/list.h) 的技术类似。

    用于在声明列表头时初始化列表,而不是尝试执行以下操作:

    // won't work:
    struct lista my_list = /* something or other */;
    

    Linux 使用一个宏来执行声明和初始化(因此用户仍然必须只使用一次名称)。对于您的struct lista,它可能看起来像:

    #define LISTA_HEAD struct lista name = LISTA_INIT_EMPTY(name)
    
    // this is all the user needs to do to both declare and initialize a list:
    LISTA_HEAD(my_list);
    

    查看include/linux/list.h 了解所有详细信息。对于列表操作的工作原理也有很好的解释(并非所有内容都是直观的):

    【讨论】:

      【解决方案3】:

      真的没有!如果您将空定义为 NULL 而不是“自身”,那么您可以这样做:

      #define LISTA_INIT_EMPTY {NULL,NULL}

      【讨论】:

        【解决方案4】:

        显然这是不可能的,因为块需要知道实例。

        由于类型不匹配,.next = &.next 也将不起作用。 (struct lista*struct lista**

        【讨论】:

          【解决方案5】:

          不,您的初始化程序会创建一个struct lista,然后将my_list 分配给它。在这种情况下,您对 this 的想法没有意义,在分配之前它不会指向 my_list

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-07-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-10-19
            相关资源
            最近更新 更多