为什么在以下结构定义中需要显式转换

Dav*_*542 6 c struct initialization literals compound-literals

随着struct通过复合文字初始化时,它会做铸件本身。例如:

struct movie {
    char title[50];
    int year;
};
typedef struct movie Item;

typedef struct node {
    Item        item;
    struct node *next;
} Node;

typedef struct linkedlist {
    Node   *head;
    size_t size;
} LinkedList;
Run Code Online (Sandbox Code Playgroud)
LinkedList movies2 = {
    .head=&(Node){{"Avatar", 2010}, NULL},
    .size=1
};
Run Code Online (Sandbox Code Playgroud)

但是,如果我将定义分开,则必须添加显式转换:

LinkedList movies2;
movies2 = (LinkedList) {
    .head=&(Node){{"Avatar", 2010}, NULL},
    .size=1
};
Run Code Online (Sandbox Code Playgroud)

代码:https : //godbolt.org/z/dG8nMh

如果我(cast_type)在第二个中遗漏了 error: expected expression before ‘{’ token. 为什么会这样?

也就是说,为什么初始化不需要强制转换而另一个定义需要?我的想法是第二个版本应该能够在没有显式转换的情况下自行解决,但显然这是不正确的。

Vla*_*cow 1

在这两种情况下,您都使用复合文字。

\n

在声明中的第一种情况下

\n
LinkedList movies2 = {\n    .head=&(Node){{"Avatar", 2010}, NULL},\n    .size=1\n};\n
Run Code Online (Sandbox Code Playgroud)\n

(Node){{"Avatar", 2010}, NULL}您正在初始化程序列表中使用该类型的复合文字,Node该列表的地址用作结构head的数据成员的初始化程序LinkedList

\n

在第二种情况下,您首先创建了一个类型的对象LimkedList

\n
LinkedList movies2;\n
Run Code Online (Sandbox Code Playgroud)\n

然后您使用赋值运算符来创建带有类型复合文字的对象LinkedList

\n
(LinkedList) {\n    .head=&(Node){{"Avatar", 2010}, NULL},\n    .size=1\n}\n
Run Code Online (Sandbox Code Playgroud)\n

那是

\n
movies2 = (LinkedList) {\n    .head=&(Node){{"Avatar", 2010}, NULL},\n    .size=1\n};\n
Run Code Online (Sandbox Code Playgroud)\n

那就是没有任何铸造。使用了两种不同的复合文字。一种是 Node 类型,另一种是 LinkedList 类型。

\n

为了说清楚。考虑一个简单的例子

\n
int x = { 10 };\n
Run Code Online (Sandbox Code Playgroud)\n

在上面的声明中,变量x由整数常量 10 初始化。

\n

也可以按照下面的方式写

\n
int tmp = { 10 };\nint x;\nx = tmp;\n
Run Code Online (Sandbox Code Playgroud)\n

这里创建了一个中间变量来初始化该变量x。复合文字实际上是一个未命名的对象。上面的代码可以重写为

\n
int x;\nx = ( int ){ 10 }; \n
Run Code Online (Sandbox Code Playgroud)\n

这里没有任何铸造。该表达式 ( int ){ 10 }创建一个由整数常量 10 初始化的类型的未命名对象。int并将这个新创建的未命名对象分配给变量x

\n

另请参阅以下问题在 C 语言中使用 \xe2\x80\x9c{}\xe2\x80\x9d 进行转换的优点是什么?

\n