7 #dene TMAX_S(type, x, y) ({ \
8 type _x = (x); \
9 type _y = (y); \
10 _x > _y ? _x: _y; })
Gcc 编译器将包含在圆括号和大括号双层括号内的复合语句看作是一个表达式,它可出现在任何允许表达式的地
方;复合语句中可声明局部变量,判断循环条件等复杂处理。而表达式的最后一条语句必须是一个表达式,它的计算
结果作为返回值。MAX_S 和 TMAX_S 宏内就定义局部变量以消除参数副作用。
MAX_S 宏内(void)(&_x == &_y)语句用于检查参数类型一致性。当参数 x 和 y 类型不同时,会产生”
comparisonofdistinctpointertypeslacksacast”的编译警告。
注意,MAX_S 和 TMAX_S 宏虽可避免参数副作用,但会增加内存开销并降低执行效率。若使用者能保证宏参数
不存在副作用,则可选用普通定义(即 MAX 宏)。
5. 得到一个成员在结构体中的偏移量(lint 545 告警表示"&用法值得怀疑",此处抑制该警告):
1 #dene FPOS(type, eld) \
2 /*lint -e545 */ ((int)&((type *)0)-> eld) /*lint +e545 */
6. 得到一个结构体中某成员所占用的字节数:
1 #dene FSIZ(type, eld) sizeof(((type *)0)->eld)
7. 按照 LSB 格式把两个字节转化为一个字(word):
1 #dene FLIPW(arr) ((((short)(arr)[0]) * 256) + (arr)[1])
8. 按照 LSB 格式把一个字(word)转化为两个字节:
1 #dene FLOPW(arr, val) \
2 (arr)[0] = ((val) / 256); \
3 (arr)[1] = ((val) & 0xFF)
9. 得到一个变量的地址:
1 #dene B_PTR(var) ((char *)(void *)&(var))
2 #dene W_PTR(var) ((short *)(void *)&(var))
10. 得到一个字(word)的高位和低位字节:
1 #dene WORD_LO(x) ((char)((short)(x)&0xFF))
2 #dene WORD_HI(x) ((char)((short)(x)>>0x8))
11. 返回一个比 X 大的最接近的 8 的倍数:
1 #dene RND8(x) ((((x) + 7) / 8) * 8)
12. 将一个字母转换为大写或小写:
1 #dene UPCASE(c) (((c) >= 'a' && (c) <= 'z') ? ((c) + 'A' - 'a') : (c))
2 #dene LOCASE(c) (((c) >= 'A' && (c) <= 'Z') ? ((c) + 'a' - 'A') : (c))
注意,UPCASE 和 LOCASE 宏仅适用于 ASCII 编码(依赖于码字顺序和连续性),而不适用于 EBCDIC 编码。
13. 判断字符是不是 10 进值的数字:
1 #dene ISDEC(c) ((c) >= '0' && (c) <= '9')
评论0