【问题标题】:Referencing an anonymous struct in itself本身引用匿名结构
【发布时间】:2021-08-02 06:46:52
【问题描述】:
typedef struct {
    //
} list;

typedef struct list{
    //
} list;

我在另一篇文章(例如Using an anonymous struct vs a named struct with typedef)中读到,其中说这两者几乎是等价的,唯一需要后者的时候是在引用结构本身时。

但是,使用 clang 和 gcc 可以很好地编译以下内容:

#include <stdio.h>

typedef struct {
    struct list *next;
} list;

int main(){
 list l;
 return  0;
}

上面我有一个匿名结构引用它自己。这是如何编译的?

【问题讨论】:

  • struct listlist 是不同的类型。结构标签与 typedef 名称有不同的“命名空间”。如果您尝试将next 指向list,则会遇到问题
  • 您将 next 声明为指向 struct list 的指针,该指针与当前定义的结构类型无关。请注意,它与typedef struct { struct asdfasdf *next; } list; 一样“好”
  • 我明白了,所以如果我使用后者,那么struct list* 将与外部list 的类型相同?

标签: c struct declaration typedef forward-declaration


【解决方案1】:

首先,您的问题中没有匿名结构。有一些未命名结构的例子。

匿名结构的概念在 C 标准中定义如下(6.7.2.1 结构和联合说明符)

13 没有标签的结构类型的未命名成员称为 匿名结构; 没有标签的联合类型的未命名成员是 称为匿名工会。匿名结构的成员或 union 被认为是包含结构的成员或 联盟。如果包含结构或联合,则递归适用 也是匿名的。

至于这份声明

typedef struct {
    struct list *next;
} list;

然后声明了两种不同的类型:别名为list 的未命名结构和类型为struct list 的不完整声明。 liststruct list 是两种不同的不兼容类型。

例如,如果你想试试这个简单的程序

#include <stdio.h>

typedef struct {
    struct list *next;
} list;

int main(void) 
{
    list lst1;
    list lst2;
    
    lst1.next = &lst2;
    
    return 0;
}

那么编译器会对该语句报错

lst1.next = &lst2;

说有一个从不兼容的指针类型“list *”到“struct list *”的赋值。

【讨论】:

  • 我以为没有名字的结构叫anonymous?匿名和匿名有什么区别?
  • 谢谢,我只是想澄清一下,这是前向声明,对吗?指向尚不存在的struct list(在结构内)?
  • @Dan 是的,您可以声明一个指向不完整类型的指针。
  • 具体叫什么前向声明?
  • @Dan 是的,可以认为是前向声明。
猜你喜欢
  • 1970-01-01
  • 2016-07-23
  • 2014-01-14
  • 2013-04-18
  • 2020-10-28
  • 2015-05-21
  • 2016-09-03
  • 2019-11-17
  • 2018-03-28
相关资源
最近更新 更多