是否使用类型双关在 C 标准定义的相同类型的对象之间进行转换?

问题描述 投票:0回答:1

在 C 标准的“结构和联合成员”部分中,提到以下代码的类似内容是有效的:(ISO/IEC 9899:201x,6.5.2.3.9 示例 3)

#include<stdio.h>

union point {
  struct {
    int value;
  } x;
  struct {
    int value;
  } y;
};

int main() {
  union point p;
  p.x.value = 1;
  printf("%d\n", p.y.value);
}

这是因为草案的以下部分:

为了简化联合体的使用,做出了一项特殊保证: 如果联合包含多个共享共同首字母的结构 序列(见下文),并且如果联合对象当前包含一个 这些结构中,允许检查共同的初始 其中任何一个完整类型声明的一部分 联盟的情况是可见的。两个 o 结构共享一个共同的首字母 如果相应的成员具有兼容的类型(并且,对于 位域,相同的宽度)用于一个或多个初始的序列 会员。

根据标准这也有效吗?

#include<stdio.h>

union point {
  int x;
  int y;
};

int main() {
  union point p;
  p.x = 1;
  printf("%d\n", p.y);
}

我知道这是类型双关,但是规范中是否有某种段落可以保证对象表示完全依赖于类型,因此这很好?

它也适用于更复杂的类型吗? (比如

struct
union
?)

延伸一下问题,有没有办法将

union first
对象转换为
union second
,遵循标准,并且不需要我们记住哪个变体存储在
union first
中:

union first {
  int a;
  char b;
};

union second {
  int a; 
  char b;
  float c;
};
c language-lawyer unions type-punning
1个回答
0
投票

是否使用类型双关在 C 标准定义的相同类型的对象之间进行转换?

按对象本身的类型访问对象不是类型双关。

给定

union point { int x; int y; };
union point p;
,如果一个值存储在
p.x
中,然后用
p.y
访问,则该值是
p.y
的值,根据 C 2018 6.5.2.3 3。注释 99 明确表示
p.y
的值是联合体中字节表示的值,解释为
p.y
的类型:

如果用于读取联合对象内容的成员与最后用于在对象中存储值的成员不同,则该值的对象表示形式的适当部分将被重新解释为新类型中的对象表示形式如 6.2.6 中所述(有时称为“类型双关”的过程)。这可能是一个陷阱表示。

由于联合中的字节是用于在

p.x
中存储
int
类型的值的字节,因此当解释为
int
p.y
类型时,它们表示相同的值。

© www.soinside.com 2019 - 2024. All rights reserved.