具有灵活阵列成员的不透明结构 [英] Opaque structure with flexible array member
问题描述
假设我在头文件中有一个结构声明,例如:
Suppose I have a struct declaration in a header file like:
event.h
struct event_t;
并且在相应的 C 文件中,我想使用 Linux 特定的 struct inotify_event
对其进行排序.问题在于 struct inotify_event
包含灵活的数组成员:
and in the corresponding C file I would like to sort-of alias it with the Linux-specific struct inotify_event
. The problem is that struct inotify_event
contains flexible array member:
struct inotify_event {
int wd;
uint32_t mask;
uint32_t cookie;
uint32_t len;
char name[];
};
根据 6.7.2.1(p3)
(强调我的):
结构或联合不应包含不完整或不完整的成员函数类型(因此,结构不应包含本身,但可能包含指向自身实例的指针),除了具有多个命名成员的结构的最后一个成员可能有不完整的数组类型;这样的结构(以及任何联合包含(可能递归地)这样一个结构的成员)不得是结构的成员或数组的元素.
A structure or union shall not contain a member with incomplete or function type (hence, a structure shall not contain an instance of itself, but may contain a pointer to an instance of itself), except that the last member of a structure with more than one named member may have incomplete array type; such a structure (and any union containing, possibly recursively, a member that is such a structure) shall not be a member of a structure or an element of an array.
不可能将 struct event_t
定义为
struct event_t{
struct inotify_event base; //Non-conforming
};
所以我可以将 struct event_t *
转换为 struct inotify_event *
.由于 6.7.2.1(p3)
只关注结构,我看到的解决方案是将标签名称重新声明为
So I could convert struct event_t *
to struct inotify_event *
. Since the 6.7.2.1(p3)
concerns only about structs the solution I see is to redeclare the tag name as
union event_t
然后将其定义为单个元素联合.
and then define it later as a single element union.
union event_t{
struct inotify_event event; //Conforming?
};
我发现标准对联合的唯一要求是联合的成员集必须是非空的6.2.5(p20)
(强调我的):
The only requirement the Standard imposes on union that I found is that the set of members of a union must be non-empty 6.2.5(p20)
(emphasize mine):
联合类型描述了一个重叠的非空成员对象集,每个都有一个可选的指定名称,并且可能是不同的类型.
A union type describes an overlapping nonempty set of member objects, each of which has an optionally specified name and possibly distinct type.
问题:通过union
隐藏某些特定数据结构的实现细节是否是一种符合/常见的方式?
QUESTION: Is it a conforming/common way to hide an implementation details of some specific data structure through union
?
推荐答案
到目前为止,最简单的方法是将其放入您的 event.h
标头中:
By far the simplest technique is to put this into your event.h
header:
typedef struct inotify_event event_t;
这声明了一个结构类型struct inotify_event
,并为其声明了一个别名event_t
.但是它根本没有定义struct inotify_event
的内容.
This declares that there is a structure type struct inotify_event
and declares an alias for it event_t
. But it does not define the content of struct inotify_event
at all.
只有event.c
中的实现代码包含系统头中struct inotify_event
的定义;其他所有内容均不包含该标头,并且无法访问 event_t
的元素,除非通过您定义的访问器 API.
Only the implementation code in event.c
includes the definition of struct inotify_event
from the system header; everything else does not include that header and cannot access the elements of an event_t
except through the accessor API you define.
您可以通过代码审查(或使用 grep
或其他类似技术进行检查)来强制执行这种职责分离,以确保除了您的事件类型的实现之外,没有其他代码使用系统标头 <代码>inotify_event.而且,如果您移植到 Linux 以外的系统而不支持 inotify,那么您只需在 event.h
标头中提供替代的不透明结构类型来代替 struct inotify_event
.
You can enforce this separation of duties by code review — or by checking with grep
, or other similar techniques — to ensure that no code except the implementation of your event type uses the system header for inotify_event
. And, if you port to a system other than Linux without support for inotify, then you simply provide an alternative opaque structure type in place of struct inotify_event
in your event.h
header.
这避免了所有关于结构中是否有灵活的数组成员等问题;这完全不是问题.
This avoids all questions about whether there are flexible array members within structures, etc; it is all a non-issue.
注意关于 什么是问答type 后跟 _t
(下划线 t)代表?.使用 _t
后缀创建自己的类型时要小心 ¸——考虑在此类类型名称上使用前缀,这样您的名称就有可能与系统提供的名称不同.
Note the Q&A about What does a type followed by _t
(underscore t) represent? . Be cautious about creating your own types with the _t
suffix ¸— consider using a prefix on such type names that gives you a chance that your names will be distinct from those provided by the system.
这篇关于具有灵活阵列成员的不透明结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!