gpt4 book ai didi

编译 C 结构

转载 作者:行者123 更新时间:2023-12-04 11:05:03 28 4
gpt4 key购买 nike

这是我的代码:

#include <stdio.h>
typedef struct {
const char *description;
float value;
int age;
} swag;

typedef struct {
swag *swag;
const char *sequence;
} combination;

typedef struct {
combination numbers;
const char *make;
} safe;

int main(void)
{
swag gold = { "GOLD!", 100000.0 };
combination numbers = { &gold, "6503" };
safe s = { numbers, "RAMCON" };

printf("Contents = %s\n", s.numbers.swag->description);

getchar();

return 0;
}

每当我使用 VS 开发人员控制台编译它时,我都会收到此错误:error C2440: 'initializing' : cannot convert from 'combination' to 'swag *'。但是,如果我使用 gcc,控制台只会打印:“GOLD!”。不明白这是怎么回事。

最佳答案

您偶然发现的是各种 C89/90 编译器中使用的流行非标准编译器扩展的特定于实现的变体。

经典 C89/90 的严格规则禁止在 {} 初始化程序中使用非常量对象。这立即意味着不可能在初始化程序的 {} 之间指定整个 struct 对象,因为那样会违反上述要求。根据该规则,您只能在 {} 之间使用标量常量。

但是,许多 C89/90 编译器忽略了该标准要求,并允许用户在为本地对象编写 {} 初始化程序时指定非常量值。不幸的是,如果用户在 {} 初始化器中指定了一个复杂的 struct 对象,这会立即产生歧义,就像在您的

中一样
safe s = { numbers, "RAMCON" };

语言标准不允许这样做,因此不清楚这个 numbers 初始化程序应该适用于什么。有两种解释方式:

  1. 语言的现有规则表明,编译器必须自动进入每一层 struct 嵌套,并将 {} 中的顺序初始化器应用于所有顺序标量以这种方式找到的字段(实际上,它有点复杂,但这是一般的想法)。

    这正是您的编译器所做的。它采用了第一个初始化器 numbers,它找到了第一个标量字段 s.numbers.swag 并尝试将前者应用于后者。这预计会产生您观察到的错误。

  2. 其他编译器对该扩展采取了更精细的方法。当编译器看到 {} 列表中的下一个初始化程序与左侧的目标字段具有相同类型时,它没有“打开”目标字段,也没有进入下一个嵌套级别,而是使用整个初始化值来初始化整个目标字段。

后一种行为是您在示例中所期望的(而且,如果我没记错的话,这是 C99 要求的行为),但您的 C89/90 编译器的行为与第一种方法一致。

换句话说,当您编写 C89/90 代码时,当您在本地 {} 初始值设定项中指定非常量对象时,通常可以使用该非标准扩展。但最好避免在此类初始化器中使用 struct 对象,而只使用标量初始化器。

关于编译 C 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26093970/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com