为什么匿名结构(非typedef'd)在c中有用?

时间:2018-01-06 23:10:55

标签: c struct

每当我输入

时我都意识到了
typedef struct {
//  ...
} foo;

有一个名为typedef的匿名结构。我想不出任何方法将匿名结构传递给函数,所以它似乎没用 我能想到的唯一用途就是像这样的c ++:

struct {
    char* name;
    int   age;
} alice;

void print_info(auto v) {
    printf("name: %s age: %i", v.name, v.age);
}

int main() {
    alice.name = "Alice";
    alice.age  = 24;
    print_info(alice);
}

尽管c缺少任何类似的内置多态性,但它也允许匿名结构。

有人能找到有用的情况吗?

1 个答案:

答案 0 :(得分:6)

这种un-typedef的匿名结构的用途非常有限,但使用不是很少。基本上,它们允许您将一些数据组合在一个函数或单个源文件中。

其中一个要点是在文件范围定义的任何此类变量应为static,因为没有适当的声明可用于其他文件。在单个函数内部,变量可以是自动的,也可以是static;我想如果你有struct { … } *peculiar;,那么你甚至可以管理动态分配。但是,如果你喜欢玩火和双重维护的噩梦,你实际上可以在其他源文件中引用原始变量 - 你不应该这样做!所以,有可能(但请不要这样做!):

  • file1.c

    struct { char* name; int age; } alice;
    
  • file2.c

    extern struct { char* name; int age; } alice;
    

但是,如果您需要源文件之间共享的信息,请创建标题并为结构类型指定名称(通过标记或typedef或两者)。

(为什么这样做?想想编译器在预处理后看到了什么?它看到了每个TU中的等效信息,并且如果定义/声明匹配,它会正确。但是当你拥有它时,确保它们匹配要容易得多提供它们的单个标题。)

假设你没有沉迷于这种可疑的做法,那么你是正确的,没有办法传递这些变量。因此,您可能会使用具有文件范围的结构化变量,但内部链接可以由源文件中的多个函数访问。这些设计远非闻所未闻,但它们往往有点可疑。

请注意,如果您有:

static struct {
    char* name;
    int   age;
} alice;

static struct {
    char* name;
    int   age;
} bob;

然后alicebob有不同的类型(因此您无法撰写bob = alice;alice = bob;)。

因此,总的来说,这些变量的使用有限,但不是零使用。使用这些变量很少是一个好主意,但如果有充分的理由(经得起仔细的批判性审查,最好是由几个人进行),那么你可以继续使用它们。但是你需要确定结构标签的成本是不可接受的。 (我至少会添加结构标记,如果只是为了更好地记录它代表什么。)