Bad warning or not
In SunStudio12 rh4, I get the following warning
"/xxx.h", line 92: Warning: Types cannot be declared in anonymous union.
Code is from
union
{
struct
{
doublexStart;/* 256 - 263 */
doublexDelta;/* 264 - 271 */
uint32_t xUnits;/* 272 - 275 */
} adjunct_1000;
struct
{
doublerowStart;/* 256 - 263 */
doublerowDelta;/* 264 - 271 */
uint32_t rowUnits;/* 272 - 275 */
uint32_t columnRecs;/* 276 - 279 */
doublecolumnStart; /* 284 - 291 */
doublecolumnDelta; /* 292 - 299 */
uint32_t columnUnits; /* 300 - 303 */
} adjunct_2000;
struct
struct
{
doubletagStart;/* 256 - 263 */
doubletagDelta;/* 264 - 271 */
uint32_t tagUnits;/* 272 - 275 */
uint32_t numberSubrec; /* 276 - 279 */
doubler2Start;// 280 - 287| Unused. Set to tagStart.
doubler2Delta;// 288 - 295| Unused. Set to tagDelta.
uint32_t r2Units;// 296 - 299| Unused. Set to tagUnits.
uint32_t recordLength; /* 300 - 303 */
struct
{
charname [4];
charformat[2];
uint16_t offset;
} subr[26];
} adjunct_3000;
};
I think this is legal. IBM's web site certainly seems to say this is ok. (this is within a big structuer).
Comments?
# 5
The C++ standard could not be more clear: nested types cannot be declared in an anonymous union.
Old Sun compilers incorrectly accepted the code without complaint. The C++ standard requires a diagnostic message. In order not to break working code, more recent compilers (since C++ 5.6 in 2004) emit only a warning.
If you don't want to see the warning, you can fix the code so that it conforms to the standard (best and most portable option), or disable the compiler warning by adding the option
-erroff=anonnotype
For more on disabling warnings, refer to the C++ Users Guide option reference for the -errtags and -erroff options.
# 7
There are two separate issues.
1. An anonymous union at global or namespace scope must be declared static.
2. An anonymous union cannot declare nested types.
Your original example showed an anonymous union at global scope that was not declared static, and that declared nested types.
You later revised the example to show the anonymous union as a member of a struct, but it still declared nested types.
Your new example is similar to the revised example. The anonymous union is a member of a struct, which is always OK. But the anonymous union declares two nested structs, which is not OK.
You can make the example valid by naming the structs and moving them outside the anonymous union:
struct S1 {
int b;
int c;
};
struct S2 {
int d;
int e;
};
struct my_struct {
int a;
union {
S1 s1;
S2 s2;
};
};
or like this, to preserve some scope:
struct my_struct {
int a;
struct S1 {
int b;
int c;
};
struct S2 {
int d;
int e;
};
union {
S1 s1;
S2 s2;
};
};