在FreeBSD中分析IPv6源代码时,得出几条C语言代码编写技巧:
1、根据宏定义来实现对不同网络的支持,这样的switch语句中结合宏定义套用预编译指令,有利于减小编译后的内核大小,使得程序结构更清晰,运行更快;如在if_ethersub.c中switch模块:
switch (ether_type) {
#ifdef INET
case ETHERTYPE_IP:
......break;
case ETHERTYPE_ARP:
........ break;
#endif
#ifdef IPX
case ETHERTYPE_IPX:
....... break;
#endif
#ifdef INET6
case ETHERTYPE_IPV6:
....... break;
#endif
#ifdef NETATALK
case ETHERTYPE_AT:
....... break;
case ETHERTYPE_AARP:
....... break;
#endif
default:
....... break;
}
2、对需要频繁处理的模块,加入到一个文件模块中。节点在处理接收到的数据报时,因为每个节点都需要对扩展首部中的逐跳选项首部进行处理,所以把此模块编辑到和IPv6头部一起处理的ip6_input模块中,其他扩展首部并不是都需要处理的,有的只在源或者目的主机才处理,如FRAG分片首部。这样加快数据报的处理,提高网络速度。
3、Goto语句的使用。在一个函数中,若有很多相同功能的小模块(10行左右),可以集合到一起,如出错处理等,通过goto联系起来。这样的模块一般放在函数的尾部,使得程序结构更加清晰;
4、复杂数据结构的简单化。可以通过#define来对复杂数据结构成员的重新定义,这样使结构变量更直观,方便维护和阅读;如:
struct ip6_hdr {
union {
struct ip6_hdrctl {
u_int32_t ip6_un1_flow;
u_int16_t ip6_un1_plen;
u_int8_t ip6_un1_nxt;
u_int8_t ip6_un1_hlim;
} ip6_un1;
u_int8_t ip6_un2_vfc;
} ip6_ctlun;
struct in6_addr ip6_src;
struct in6_addr ip6_dst;
} ;
#define ip6_vfc ip6_ctlun.ip6_un2_vfc
#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt
#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim
#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim
5、类函数宏调用(也叫带参数的宏)和函数调用,这是一个在C中很明显的时空转换问题。类函数宏的反应时间快、占用空间多;函数则相反,时间响应慢、空间占用低。在预处理的时候,类函数宏就被编译到源程序中,这样不存在调用时间的问题,而函数相对来说则是独立的,在需要时才去调用——动态调用。如类函数宏:
#define panic(param) { printf(param); exit(-1); }
若是小功能模块,可以考虑用类函数宏实现,方便快捷。
本文介绍在FreeBSD中分析IPv6源代码得出的C语言代码编写技巧。包括结合宏定义与预编译指令减小编译内核大小,将频繁处理模块集中,合理使用goto语句,简化复杂数据结构,以及根据情况选择类函数宏或函数调用,以提升程序性能和可读性。
1万+

被折叠的 条评论
为什么被折叠?



