C 访问非活动工会成员

C 访问非活动工会成员,c,c99,unions,C,C99,Unions,如果我有以下代码: #include <stdint.h> union data_t { int8_t sbyte; uint8_t ubyte; int16_t sint; uint16_t uint; int32_t slong; uint32_t ulong; int64_t sint64; uint64_t uint64; float qsingle; double qdouble; long double qfloat; }; u

如果我有以下代码:

#include <stdint.h>
union data_t {
  int8_t sbyte;
  uint8_t ubyte;
  int16_t sint;
  uint16_t uint;
  int32_t slong;
  uint32_t ulong;
  int64_t sint64;
  uint64_t uint64;
  float qsingle;
  double qdouble;
  long double qfloat;
};
union data_t *data;
data = malloc(sizeof(union data_t));
data.uint = 2534;
#包括
联合数据{
int8_t sbyte;
uint8_t ubyte;
int16_t sint;
uint16_t uint;
国际贸易;
uint32_t ulong;
int64_t sint64;
uint64_t uint64;
浮球;
双qdouble;
长双叶;
};
联合数据_t*数据;
数据=malloc(sizeof(union data_t));
data.uint=2534;

在这里,我已经将uint16_t类型指定为42,我可以安全地访问一个小于我所指定的数据类型(例如uint8_t)的数据类型,并让它安全地进行类型转换(到230)?这个答案()似乎表明它在C11中是允许的,但我不确定这在C99中是否合法。

这可能是特定于编译器的,因为它在联合体中如何排列基础数据。本质上,“非活动”成员的访问只是以不同的方式解释数据。将大整数解释为小整数应该是可行的

float
解释为
int
或反之不太可能起作用,因为底层位没有意义:

[0x1|0xF|0x7FFFFF]
           ^ 23-bit mantissa
      ^ 8-bit exponenent
  ^ sign bit

它可能是特定于编译器的,因为它在联合体中如何安排基础数据。本质上,“非活动”成员的访问只是以不同的方式解释数据。将大整数解释为小整数应该是可行的

float
解释为
int
或反之不太可能起作用,因为底层位没有意义:

[0x1|0xF|0x7FFFFF]
           ^ 23-bit mantissa
      ^ 8-bit exponenent
  ^ sign bit

这个问题的答案在C99或C11中没有很好的定义。在这两项标准中,§6.2.6.1p7规定:

当值存储在联合类型的对象的成员中时 与之不对应的对象表示形式的字节数 成员,但与其他成员相对应,并采用未指定的值


设置不同的成员后,我肯定会看到访问
qsingle
qdouble
qfloat
成员时出现问题。这些成员可能具有导致引发信号(如
SIGFPE
)的表示,并且从此类信号处理程序返回是未定义的行为。

此问题的答案在C99或C11中没有明确定义。在这两项标准中,§6.2.6.1p7规定:

当值存储在联合类型的对象的成员中时 与之不对应的对象表示形式的字节数 成员,但与其他成员相对应,并采用未指定的值


设置不同的成员后,我肯定会看到访问
qsingle
qdouble
qfloat
成员时出现问题。这些成员可能具有导致引发信号(如
SIGFPE
)的表示,并且从此类信号处理程序返回是未定义的行为。

好的,谢谢。我不打算从浮点数转换到r,只需要整数。如果它像你说的那样是特定于编译器的,我想我会避免它。好的,谢谢你。我不打算从浮点数转换到r,只需要整数。如果它像你说的那样是特定于编译器的,我想我会尽量避免它。
[0x1|0xF|0x7FFFFF]
           ^ 23-bit mantissa
      ^ 8-bit exponenent
  ^ sign bit