How to use c union nested in struct with no name
Solution 1
This is an anonymous union. In C++, as per [class.union], paragraph 5:
For the purpose of name lookup, after the anonymous union definition, the members of the anonymous union are considered to have been defined in the scope in which the anonymous union is declared
This means you can access its members as if they were members of RC_model_t_st
.
Solution 2
Without being sure and without having tried:
The union itself is not accessible, but it's members are.
Therefore you should be able to do refer to obj.block
and obj.grid
Solution 3
To elaborate on the answer provided by Angew quoting the standard concerning anonymous unions and structs, I thought to provide an sample of C source code with the output generated by that sample showing how values are allocated within a struct
and a union
composed of struct
and union
components.
The standard quoted by Angew is:
For the purpose of name lookup, after the anonymous union definition, the members of the anonymous union are considered to have been defined in the scope in which the anonymous union is declared.
The source code of a struct
composed of named and anonymous structs and unions looks like the following. This is using Visual Studio 2005 and the #pragma (pack, 1)
is used to align everything on a char
boundary in order for there to be no memory holes. There is also a simple C Preprocessor macro defined to make the output more legible and easier to code.
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.u.s
} 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.u.s.iOne; PRINTF_VAL(Things.u.s.iOne);
jj = Things.u.s.iTwo; PRINTF_VAL(Things.u.s.iTwo);
jj = Things.u.s.iThree; PRINTF_VAL(Things.u.s.iThree);
return iMatch + 1;
}
The output generated by this function looks like:
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.u.s.iOne 8
Things.u.s.iTwo 9
Things.u.s.iThree 10
The output shows the overlap between the various components of the main struct
, Things
caused by the use of unions. You can also see how the components of the anonymous struct
and union
are referenced versus those components of the named struct
and union
.
Also just for fun I tried adding an array definition of const UCHAR myArray[];
after the anonymous union
containing const UCHAR myArray[];
to see what would happen. The compiler complained with an error of error C2020: 'myArray' : 'struct' member redefinition
. The addition is commented out in the struct
definition of Things
above. However since the second use of const UCHAR myArray[];
is in a named union
the compile works because second use is accessed by specifying the name of the union.
Solution 4
This code here (https://gist.github.com/klange/4042963) shows how to access anonymous unions inside struct. You just access the members of nested union as if they are members of the 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
}
};
Solution 5
Names declared in an anonymous union are used directly, like nonmember variables. A good reason to do this is to save memory.
#include <iostream>
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;
}
Related videos on Youtube
zwx
Updated on February 14, 2020Comments
-
zwx over 4 years
I'm working on the so called Hotspot open source project, and looking at the implementation I found a nasty nested union in struct looking like that:
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;
As far as I'm aware in C/C++ that union is unaccesible. So how someone can make use of union declared in such manner and for what purpose?
Thanks!
-
zch over 11 years
-
-
zwx over 11 yearsYou mean that obj is RC_model_t?
-
zwx over 11 yearsOk. Then if I can access them as members of the structure, I don't understand why would someone put them in anonymous union?
-
zwx over 11 yearsThis is the most complete answer for me. Thanks!
-
Angew is no longer proud of SO over 11 years@zwx Because it's still a union - they occupy the same storage space.
-
Atmocreations over 11 yearsWith every variable, you allocate some memory space of n bytes. Now the variables type defines only, how much space and how the content of this space is to be interpreted. With a union, the variable uses the space of the biggest type, the interpretation depends on the member you access
-
Atmocreations over 11 years@akp: Pay attention. Alignment could break this depending on the architecture
-
Sergey Skopus over 7 yearsThe answer is not exact. The question was about ANONYMOUS union, the answer is about a union having a name
-
theEpsilon about 7 yearsThis doesn't answer the question.
-
Brad Pitt over 5 yearsif you put out the results of your code, that's gonna be more helpful. (though we can run it by ourself)