C中的递归联合定义

时间:2018-09-27 19:22:00

标签: c binary-search-tree unions

我想制作类似于二进制搜索树的结构,用于将地址映射到Page *(除非它实际上是十六进制的,并且该地址由结构本身暗示),所以:

typedef union Map Map;
union Map {
    Map (*ps)[16];
    Page *p;
};

从逻辑上讲这是完全合理的(并集Map包含指向Page的指针或指向包含16个Map s的数组的指针),但是{ {1}}与ps一起声明,因此我猜想C中不允许这种递归定义。

是否有任何方法可以使用指针别名之类的技巧?

1 个答案:

答案 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],因为看起来编译器此时并不需要有关指向类型的完整信息。