struct S { int align; 之间的区别}; (在 struct 关键字之后命名)和 struct { int align; } S; (结构定义后的名称)

Difference between struct S { int align; }; (name after struct keyword) and struct { int align; } S; (name after the struct definition)

#include <stdio.h>

struct Header
{
    unsigned long long int alignment;
};

int main(void)
{
    struct Header header;  // note: we can loose the 'struct' in C++
    struct Header* pheader = &header;

    return 0;
}

上面的程序在 C 和 C++ 中都能完美编译。

但是当我将 Header 结构更改为:

struct {
    unsigned long long int alignment;
} Header;

它失败并在 C 中显示以下消息: error: storage size of ‘Header’ isn’t known

在 C++ 中: error: aggregate ‘main()::Header header’ has incomplete type and cannot be defined struct Header header;

K&R在C编程语言一书中的Storage Allocator的实现中使用了类似的结构。我以为这是同一件事,但我了解到事实并非如此。从那以后,我也在其他地方看到过。我当然更熟悉第一个版本。第二个是什么意思,它为什么存在?有什么不同?

当你编译以下部分时

struct {
    unsigned long long int alignment;
} Header;

struct没有标签,称为匿名结构类型。在做

struct Header header;

编译器产生类似

的错误

Header header’ has incomplete type and cannot be defined struct Header header

因此在这些情况下,最好 typedef struct。例如

typedef struct {
    unsigned long long int alignment;
} Header;

struct Header {}; 引入了一个名为 Header.

struct 类型

typedef struct {} Header; 引入了一个匿名结构类型,以及该匿名类型的别名 Header

struct {} Header; 引入了匿名结构类型和名为 Header 的匿名类型变量。

当没有名为 Header 的类型时(最后一种情况),struct Header header; 引入一个名为 Header 且没有主体的 struct 类型,然后尝试创建一个该类型的变量 header

简单来说,编译器看到 "Header" 并且没有 "Header" 的先前或内置数据类型,因此它不知道它是什么。当你使用

typedef struct header {
    ....
} Header;

编译器可以说,嘿,用户告诉我定义的数据类型,现在我可以稍后在代码中引用一些东西。