【发布时间】:2017-01-18 13:44:10
【问题描述】:
我遇到了一段代码,它似乎同时使用了不同的成员联合:
XEvent ev;
if(handler[ev.type])
(handler[ev.type])(&ev);
Handler 是一个函数数组。 XEvent的定义如下:
typedef union _XEvent{
int type;/*must not be changed*/
XAnyEvent xany;
XKeyEvent xkey;
XButtonEvent xbutton;
............
} Xevent;
XEvent 的所有结构成员都有一个 int 作为第一个成员。被调用的函数使用了适当的 XEvent 成员结构。
void
kpress(XEvent *ev) {
XKeyEvent *e = &ev->xkey;
问题在于XKeyEvent 似乎也使用其第一个 int 成员的值来确定事件是按键还是释放。
typedef struct {
int type; /* KeyPress or KeyRelease */
unsigned long serial; /* # of last request processed by server */
.............
} XKeyEvent;
我在这里错过了什么?
注意:以上代码属于简单终端,终端仿真器。并且所有提到的数据结构都属于Xlib。
【问题讨论】:
-
假设有一个
int(在原始的union中)重叠的结构与初始值是“安全的”(我的猜测是它不能保证是,但可能是“有效的” "),那么我认为XKeyEvent的读取该值没有问题(大概KeyPress和KeyRelease是XEvent处理的两个更广泛的事件类型) .不过,struct { int type; union { .... } }可能会更安全。 -
@TripeHound:除了你有两个
types,一个在外部结构中,一个在union中的每个其他类型之前。似乎目标是让type可读,而不管存储了哪个X*Event。 -
@shadowranger 这正是重点 - X11 系统将事件作为不透明结构发送。如果有人想知道里面有什么,他可以检查
type成员并相应地强制转换联合以访问实际的数据成员。那是某种“C 中的 OOP” -
似乎这只是声明
typedef struct _XEvent{ int type; union { XAnyEvent xany; XKeyEvent xkey; XButtonEvent xbutton;}的一种混淆方式,其中每个结构 XAnyEvent 等都没有type成员。 -
@Lundin 它使编码更容易,有时甚至更清晰 - 您可以通过 with 和 without 访问事件类型内部结构。