为了阐述由Angew引用有关匿名联合和结构的标准的答案,我想提供一份C源代码示例和该示例生成的输出,展示在由struct和union组成的匿名struct和union组件内如何分配值。
Angew引用的标准是:
“为了进行名称查找,在匿名联合定义之后,匿名联合的成员被认为是在声明匿名联合所在的范围中定义的。”
以下是由命名和匿名struct和union组成的struct的源代码。这里使用的是Visual Studio 2005,并且使用#pragma (pack, 1)将所有内容对齐到char边界,以便没有内存空洞。还定义了一个简单的C预处理器宏,使输出更易于阅读和编码。
typedef unsigned char UCHAR;
#pragma pack(push, 1)
const struct {
union {
const UCHAR myArray[];
struct {
const UCHAR iOne;
const UCHAR iTwo;
const UCHAR iThree;
};
};
union {
const UCHAR myArray[];
struct {
const UCHAR iOne;
const UCHAR iTwo;
const UCHAR iThree;
} s;
} u;
} Things = {1, 2, 4, 8, 9, 10, 22, 23, 24, 25};
#pragma pack(pop)
#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;
}
该函数生成的输出如下所示:
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
输出显示了使用联合体导致的主要
struct
Things
各个组件之间的重叠部分。您还可以看到匿名
struct
和
union
的组成部分与命名
struct
和
union
的组成部分相比如何被引用。
另外,仅仅出于好奇,我尝试在包含
const UCHAR myArray[];
的匿名
union
之后添加一个
const UCHAR myArray[];
的数组定义,以查看会发生什么。编译器报错:
error C2020: 'myArray' : 'struct' member redefinition
。上面
Things
的
struct
定义中已经将此项添加注释。但是由于第二次使用
const UCHAR myArray[];
是在命名
union
中,因此编译可以通过,因为第二次使用是通过指定union的名称来访问的。