如何使用嵌套在没有名称的struct中的c union

我正在研究所谓的Hotspot开源项目,看看实现我在struct中找到了一个令人讨厌的嵌套联合:

typedef struct RC_model_t_st { union { struct block_model_t_st *block; struct grid_model_t_st *grid; }; /* block model or grid model */ int type; thermal_config_t *config; }RC_model_t; 

据我所知,在C / C ++中,联合是不可接受的。 那么有人如何利用以这种方式和目的宣布的工会呢?

谢谢!

首先,我想说一个联合,是一个不同类型的变量的集合,就像一个结构。 但是,对于工会,您一次只能在一个字段中存储信息。

联合基本上用于节省内存, 它的大小等于联盟中最大的成员。

要访问union的数据字段,请使用点运算符(。),就像对结构一样,并由@Atmocreations解释。 将值分配给一个成员时,其他成员会因为共享相同的内存而被剔除。

作为工会可能有用的例子是

 union time { long time_in_sec; double time_in_mili_sec; }mytime; 

….上面的联合可用于存储当前时间(以秒为单位)以保持精确到一秒的时间。 或者它可以用来保持精确到毫秒的时间。 据推测,有时你会想要一个或另一个,但不是两个。 这个声明应该看起来很熟悉 它与结构定义相同,但使用关键字union而不是struct。

欲了解更多信息,请访问http://msdn.microsoft.com/en-us/library/5dxy4b7b(v=vs.80).aspx

这是一个匿名联盟。 在C ++中,根据[class.union],第5段:

出于名称查找的目的,在匿名联合定义之后,匿名联合的成员被认为已在声明匿名联合的作用域中定义。

这意味着您可以像访问RC_model_t_st一样访问其成员。

没有确定,没有尝试过:

工会本身是无法访问的,但它的成员是。

因此,您应该可以参考obj.blockobj.grid

这里的代码( https://gist.github.com/klange/4042963 )显示了如何在struct中访问匿名联合。 您只需访问嵌套联合的成员,就好像它们是结构的成员一样。

 typedef struct { union { char * company; char * school; char * project; }; union { char * location; char * url; }; union { char * title; char * program; }; time_t started; time_t left; char * description[]; } thing_t; typedef thing_t job_t; job_t yelp = { .company = "Yelp, Inc.", .location = "San Francisco, CA", .title = "Software Engineer, i18n", .started = 1339977600, .left = CURRENT, .description = { "Developed several internal tools and libraries", "Provided critical input and design work for Yelp's launch in Japan", NULL } }; 

在匿名联合中声明的名称将直接使用,如非成员变量。 这样做的一个很好的理由是节省内存。

 #include  int main(int argc, char **argv) { union { double first; double second; }; first = 10.001; second = 3.141592; std::cout << first << " " << second << std::endl; first = 10.002; std::cout << first << " " << second << std::endl; } 

为了详细阐述Angew引用有关匿名联合和结构的标准的答案,我想提供一个C源代码示例,其中该示例生成的输出显示了如何在struct中分配值以及由structunion组成的union组件。

Angew引用的标准是:

出于名称查找的目的,在匿名联合定义之后,匿名联合的成员被认为已在声明匿名联合的作用域中定义。

由命名和匿名结构和联合组成的struct的源代码如下所示。 这是使用Visual Studio 2005, #pragma (pack, 1)用于对齐char边界上的所有内容,以便没有内存空洞。 还定义了一个简单的C预处理器宏,使输出更清晰,更容易编码。

 typedef unsigned char UCHAR; // use of Microsoft Visual Studio pragma to force char alignment for the struct. #pragma pack(push, 1) const struct { union { const UCHAR myArray[]; // this array shares memory with struct following struct { const UCHAR iOne; const UCHAR iTwo; const UCHAR iThree; }; // anonymous struct accessed by specifying Things. }; // anonymous union accessed by specifying Things. // const UCHAR myArray[]; // will cause error - "error C2020: 'myArray' : 'struct' member redefinition" union { const UCHAR myArray[]; // this array shares memory with struct following struct { const UCHAR iOne; const UCHAR iTwo; const UCHAR iThree; } s; // named struct accessed by specifying Things.us } u; // named union accessed by specifying Things.u } Things = {1, 2, 4, 8, 9, 10, 22, 23, 24, 25}; #pragma pack(pop) // a little helper macro to make the output easier to code. #define PRINTF_VAL(x) printf ("%s %d \n", #x, x) int itSelf (UCHAR iMask) { int iMatch = -1; int jj = 0; jj = Things.myArray[0]; PRINTF_VAL(Things.myArray[0]); jj = Things.myArray[1]; PRINTF_VAL(Things.myArray[1]); jj = Things.myArray[2]; PRINTF_VAL(Things.myArray[2]); jj = Things.myArray[3]; PRINTF_VAL(Things.myArray[3]); jj = Things.myArray[4]; PRINTF_VAL(Things.myArray[4]); jj = Things.iOne; PRINTF_VAL(Things.iOne); jj = Things.iTwo; PRINTF_VAL(Things.iTwo); jj = Things.iThree; PRINTF_VAL(Things.iThree); jj = Things.u.myArray[0]; PRINTF_VAL(Things.u.myArray[0]); jj = Things.u.myArray[1]; PRINTF_VAL(Things.u.myArray[1]); jj = Things.u.myArray[2]; PRINTF_VAL(Things.u.myArray[2]); jj = Things.u.myArray[3]; PRINTF_VAL(Things.u.myArray[3]); jj = Things.u.myArray[4]; PRINTF_VAL(Things.u.myArray[4]); jj = Things.usiOne; PRINTF_VAL(Things.usiOne); jj = Things.usiTwo; PRINTF_VAL(Things.usiTwo); jj = Things.usiThree; PRINTF_VAL(Things.usiThree); return iMatch + 1; } 

此函数生成的输出如下所示:

 Things.myArray[0] 1 Things.myArray[1] 2 Things.myArray[2] 4 Things.myArray[3] 8 Things.myArray[4] 9 Things.iOne 1 Things.iTwo 2 Things.iThree 4 Things.u.myArray[0] 8 Things.u.myArray[1] 9 Things.u.myArray[2] 10 Things.u.myArray[3] 22 Things.u.myArray[4] 23 Things.usiOne 8 Things.usiTwo 9 Things.usiThree 10 

输出显示主struct的各个组件之间的重叠,由使用联合引起的Things 。 您还可以看到如何引用匿名structunion的组件与命名structunion组件。

另外,为了好玩,我尝试添加const UCHAR myArray[];的数组定义const UCHAR myArray[]; 在包含const UCHAR myArray[];的匿名union之后const UCHAR myArray[]; 看看会发生什么。 编译器抱怨error C2020: 'myArray' : 'struct' member redefinition 。 添加在上面的Thingsstruct定义中被注释掉。 但是自从第二次使用const UCHAR myArray[]; 在编译工作的命名union ,因为通过指定联合的名称来访问第二次使用。