gpt4 book ai didi

c - 关于 C 中 union 的问题 - 存储为一种类型并读取为另一种类型 - 它是实现定义的吗?

转载 作者:太空狗 更新时间:2023-10-29 16:23:00 25 4
gpt4 key购买 nike

我从 K&R 读到关于 C 中的 union ,据我所知, union 中的单个变量可以包含多种类型中的任何一种,如果某些东西存储为一种类型并提取为另一种类型,则结果纯粹是实现定义的.

现在请检查这段代码:

#include<stdio.h>

int main(void)
{
union a
{
int i;
char ch[2];
};

union a u;
u.ch[0] = 3;
u.ch[1] = 2;

printf("%d %d %d\n", u.ch[0], u.ch[1], u.i);

return 0;
}

输出:

3 2 515

在这里,我在 u.ch 中赋值,但同时从 u.chu.i 中检索。它是实现定义的吗?还是我在做一些非常愚蠢的事情?

我知道这对其他大多数人来说可能看起来很新手,但我无法弄清楚该输出背后的原因。

谢谢。

最佳答案

这是未定义的行为。 u.iu.ch 位于相同的内存地址。因此,写入一个并从另一个读取的结果取决于编译器、平台、体系结构,有时甚至是编译器的优化级别。因此 u.i 的输出可能并不总是 515

例子

例如,我的机器上的 gcc 会为 -O0-O2 生成两个不同的答案。

  1. 因为我的机器有 32 位小端架构,使用 -O0 我最终将两个最低有效字节初始化为 2 和 3,两个最高有效字节未初始化。所以 union 的内存看起来像这样:{3, 2, garbage, garbage}

    因此我得到类似于 3 2 -1216937469 的输出。

  2. 使用 -O2,我得到了 3 2 515 的输出,这使得 union 内存 {3, 2, 0, 0}gcc 使用实际值优化了对 printf 的调用,因此程序集输出看起来等效于:

    #include <stdio.h>
    int main() {
    printf("%d %d %d\n", 3, 2, 515);
    return 0;
    }

    值 515 可以按照此问题的其他答案中的其他解释获得。从本质上讲,这意味着当 gcc 优化调用时,它选择了零作为未初始化 union 的随机值。

写给一个 union 成员并从另一个 union 成员那里读取通常没有多大意义,但有时it may be useful for programs compiled with strict aliasing .

关于c - 关于 C 中 union 的问题 - 存储为一种类型并读取为另一种类型 - 它是实现定义的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1812348/

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