如果发生这种情况,并且我们用两个值初始化联合,我知道它将接受int数字,但我真的想知道幕后发生了什么
#include <stdio.h>
typedef union x
{
int y;
char x[6];
};
int main(void)
{
union x first={4,"AAAAAA"};
printf("%d\n",first.y);
printf("%s\n",first.x);
return 0;
}
发布于 2018-10-15 01:53:57
这段代码编译了吗?它不应该。每次重新使用联合时,分配的内存都会被覆盖。您可以定义具有多个成员的联合,但在任何给定时间只能有一个成员包含一个值。联合提供了一种将同一内存位置用于多用途的有效方法。
发布于 2018-10-15 05:41:15
问题中的代码不应该在没有对联合变量的“太多初始化器”进行诊断的情况下进行编译。您可能还会收到有关useless storage class specifier in empty declaration
的警告,因为typedef
实际上并没有为union x
定义别名。
假设您修改了代码以使用指定的初始化器,如下所示:
#include <stdio.h>
union x
{
int y;
char x[6];
};
int main(void)
{
union x first = { .y = 4, .x = "AAAAA" };
printf("%d\n", first.y);
printf("%s\n", first.x);
return 0;
}
这将编译并运行,但是当编译器设置为fussy时,您可能会收到类似于warning: initialized field overwritten [-Woverride-init]
的警告。
请注意,在上面显示的.x
的初始化器中,比原来少了一个A
。这确保了该值是一个(以null结尾的)字符串,而不仅仅是一个字节数组。在此上下文中,.x
的指定初始值设定项覆盖了.y
的指定初始值设定项,因此.x
中的值是完全有效的。例如,我得到的输出是:
1094795585
AAAAA
正如预期的那样,十进制数与十六进制0x41414141
相对应。
请注意,我删除了毫无意义的typedef
。我的默认编译规则不接受代码;我必须取消-Werror
和-Wextra
选项才能编译它。没有将警告转换为错误的-Werror
编译了带有警告的原始代码。即使添加-pedantic
也不会触发额外初始化器的错误(尽管按照标准的要求,总是会给出警告)。
https://stackoverflow.com/questions/52805318
复制相似问题