我想制作类似于二进制搜索树的结构,用于将地址映射到Page *
(除非它实际上是十六进制的,并且该地址由结构本身暗示),所以:
typedef union Map Map;
union Map {
Map (*ps)[16];
Page *p;
};
从逻辑上讲这是完全合理的(并集Map
包含指向Page
的指针或指向包含16个Map
s的数组的指针),但是{ {1}}与ps
一起声明,因此我猜想C中不允许这种递归定义。
是否有任何方法可以使用指针别名之类的技巧?
答案 0 :(得分:2)
C 2018 6.7.6.2 1指定了数组声明符的约束。它部分说:
元素类型不得为不完整或函数类型。
在Map (*ps)[16]
中,(*ps)[16]
是声明符,如语法在6.7.6 1.中所示。由于它是数组声明符,因此必须遵守规则6.7.6.2中所述,因此元素类型必须完整。即使声明的最终类型是指针,也是如此。
如评论中所述,您可以改为声明Map *ps
。如果这不能令人满意,因为ps
上的指针算法以Map
而不是Map [16]
的单位工作,则可以选择在联合之前定义typedef struct Map16 Map16;
,然后{{1 }},然后在联盟之后Map16 *ps;
。这将使struct Map16 { Map element[16]; }
上的指针算术以所需的单位工作(假设实现未填充结构,这是不寻常的),尽管它确实使您在引用元素时使用了额外的ps
。 / p>
在考虑为什么.element
不被接受Map *ps
时,我们可以看到它们都声明了指向不完整类型的指针,因此,不是它们所指向的类型的完整性而在于仅仅是C标准中的这一规则。可能是已经修改了6.7.6.2 1中的规则以允许Map (*ps)[16]
,因为看起来编译器此时并不需要有关指向类型的完整信息。