C 中的递归联合定义
Recursive union definition in C
我想制作类似二叉搜索树的东西,用于将地址映射到 Page *
s(除了它实际上是十六进制的,并且地址由结构本身隐含),所以:
typedef union Map Map;
union Map {
Map (*ps)[16];
Page *p;
};
这在逻辑上是完全合理的(联合 Map
包含指向 Page
的指针或指向 16 Map
s 的数组的指针),但是 gcc 错误在ps
声明与 array type has incomplete element type
,所以我猜这种递归定义在 C 中是不允许的。
有没有什么方法可以在不使用指针别名等技巧的情况下做到这一点?
C 2018 6.7.6.2 1 指定数组声明符的约束。它说,部分:
The element type shall not be an incomplete or function type.
在Map (*ps)[16]
中,(*ps)[16]
是一个声明符,如6.7.6的语法所示 1.由于它是一个数组声明符,所以它受6.7.6.2规则约束,因此元素类型必须完整。即使声明的最终类型是指针也是如此。
如评论中所述,您可以改为声明 Map *ps
。如果这不能令人满意,因为 ps
上的指针算法以 Map
为单位而不是 Map [16]
,另一种方法是在联合之前定义 typedef struct Map16 Map16;
,然后 Map16 *ps;
在联合内,然后在联合后 struct Map16 { Map element[16]; }
。这将使 ps
上的指针算法以所需的单位工作(假设实现不填充结构,这将是不寻常的),尽管它确实使您在引用元素时使用额外的 .element
。
考虑为什么 Map *ps
被接受而 Map (*ps)[16]
不被接受,我们可以看到两者都声明了指向不完整类型的指针,因此区分的不是指向类型的完整性它们只是 C 标准中的这条规则。可能是 6.7.6.2 1 中的规则可能已被修改为允许 Map (*ps)[16]
,因为编译器此时似乎不需要有关指向类型的完整信息。
我想制作类似二叉搜索树的东西,用于将地址映射到 Page *
s(除了它实际上是十六进制的,并且地址由结构本身隐含),所以:
typedef union Map Map;
union Map {
Map (*ps)[16];
Page *p;
};
这在逻辑上是完全合理的(联合 Map
包含指向 Page
的指针或指向 16 Map
s 的数组的指针),但是 gcc 错误在ps
声明与 array type has incomplete element type
,所以我猜这种递归定义在 C 中是不允许的。
有没有什么方法可以在不使用指针别名等技巧的情况下做到这一点?
C 2018 6.7.6.2 1 指定数组声明符的约束。它说,部分:
The element type shall not be an incomplete or function type.
在Map (*ps)[16]
中,(*ps)[16]
是一个声明符,如6.7.6的语法所示 1.由于它是一个数组声明符,所以它受6.7.6.2规则约束,因此元素类型必须完整。即使声明的最终类型是指针也是如此。
如评论中所述,您可以改为声明 Map *ps
。如果这不能令人满意,因为 ps
上的指针算法以 Map
为单位而不是 Map [16]
,另一种方法是在联合之前定义 typedef struct Map16 Map16;
,然后 Map16 *ps;
在联合内,然后在联合后 struct Map16 { Map element[16]; }
。这将使 ps
上的指针算法以所需的单位工作(假设实现不填充结构,这将是不寻常的),尽管它确实使您在引用元素时使用额外的 .element
。
考虑为什么 Map *ps
被接受而 Map (*ps)[16]
不被接受,我们可以看到两者都声明了指向不完整类型的指针,因此区分的不是指向类型的完整性它们只是 C 标准中的这条规则。可能是 6.7.6.2 1 中的规则可能已被修改为允许 Map (*ps)[16]
,因为编译器此时似乎不需要有关指向类型的完整信息。