由来:
最近在看《the Linux Programming Interface》。发现一个以前从未注意到的问题:setjmp函数的原型如下:
int setjmp(sigjmp_buf env);
此函数是用来保存当前局部一些数据,方便之后longjmp跳转到此的。令我不解的是,此sigjmp_buf看名字不是指针类型,那其怎么修改env内的值。
带着这疑问,我clone了glibc的仓库,发现其类型定义如下:
struct __jmp_buf_tag { /* NOTE: The machine-dependent definitions of `__sigsetjmp' assume that a `jmp_buf' begins with a `__jmp_buf' and that `__mask_was_saved' follows it. Do not move these members or add others before it. */ __jmp_buf __jmpbuf; /* Calling environment. */ int __mask_was_saved; /* Saved the signal mask? */ __sigset_t __saved_mask; /* Saved signal mask. */ }; typedef struct __jmp_buf_tag jmp_buf[1];
typedef struct __jmp_buf_tag sigjmp_buf[1];
尽管我自认足智多谋:),但我一开始压根没搞懂这两个typedef是啥意思(贴出sigjum_buf的是因为让大家明白这两个在glibc里是一个类型)。
于是我写了个小程序测试一下,发现此类型定义的变量类似指针类型(->能用YCM补全,.不能)。再写了个会报错的程序,gcc报其是struct __jmp_buf_tag[1]。
然后经过一分钟的思考,我明白了这是啥玩意。这就是个长度为1的__jmp_buf_tag结构数组类型。
总结一下typedef的经验,将最后一个未声明字符串(此处为jmp_buf)去掉,再去掉typedef,就是这种新类型的类型。
后言:
由于这只写了一点,所以我不好意思给此随笔另取个名字。打算以后发现什么稀罕的关于C的事都写这了。