3.1 Linux编码风格
- 参考文章:Documentation/CodingStyle
- 缩进用TAB
- {}使用:
- 对于结构体、if、for、while以及switch语句,“{”不另起一行
- 如果if、for循环后只有1行,不要加“{”和“}”
- if和else混合用的时候,else语句不另起一行
- 对于函数,“{”另起一行
- switch和case对齐
3.2 GNU C与ANSI C
- 零长度和变量长度数组
struct var_data {
int len;
char data[0]
};
int main(int argc, char *argv[])
{
int i, n = argc;
double x[n];
for(i=0; i<n; i++)
x[i] = i;
return 0;
}
- case范围:支持case x … y这样的语法,区间[x,y]中的数都会满足这个case条件
- 语句表达式:包含在括号里的语句看成一个表达式,它可以出现在任何允许表达式的地方。
- typeof关键字:其可以获得x的类型,因此可以借助typedef来定义min这个宏
#define min(x,y) ({
const typeof(x) _x = (x); \
const typeof(y) _y = (y); \
(void) (&_x == &_y); \
_x < _y ? _x : _y; \
})
- 可变参数宏,标准C就支持可变参数函数,意味着函数的参数是不固定的,如printf()函数,GNU C 中宏也可以接受可变参数目的参数,如
#define pr_debug(fmt,arg...) \
printf(fmt,##arg)
这里的arg表示其余的参数,可以是零个或多个,##是为了处理arg不代表任何参数的情况,这时候前面的逗号就显得多余了,使用##之后,CNU C 就会预处理会丢掉前面的逗号,这样
pr_debug("success!\n");
扩展为:
printk("success!\n");
- 标号元素:允许数组和结构体的元素初始化的顺序任意顺序出现。
数组初始化方式为在初始化值前添加”[INDEX]=”,或者用”[FIRST … LAST]=”的形式指定一个范围。
unsigned char data[MAX] = {[0 ... MAX] = 0};
结构体初始化方式
struct file_operations ext2_file_operation = {
.llseek = generic_file_llseek,
.read = generic_file_read,
...
};
- 当前函数名:FUNCTION或者func保存当前函数的名字
- 特殊属性声明:GUN C允许申明函数、变量和类型的特殊属性,以便手动优化和定制代码检查的方法,申明方法:在申明后加上attribute((ATTRIBUTE)). ATTRIBUTE为属性说明,若存在多个则逗号隔开。
- 内建函数:不属于标准库的内建函数通常以__builtin开始
- do{} while语句:其主要用于宏定义中,为了保证宏定义的使用者不会出现编译错误,他不对其他使用则做任何假设。
- goto语句:一般只限于错误处理中