鉴于我们日后要70岁才退休,社保要交40年的中国特色的趋势
我们程序员没有理由不珍惜生命,让编译器做更多的事情
先看main.c 文件如下:
#include <stdio.h>
#include <stdlib.h>
extern int sys_read();
extern int sys_write();
#define __NR_syscalls 100
#define __SYSCALL(nr, call) [nr] = (call),
void *sys_call_table[__NR_syscalls] = {
#include "systemcall.h"
};
int main()
{
for(;;);
return 0;
}
systemcall.h 文件如下:
而在unistd.h头文件中(linux的系统调用有几百个):
#define __NR_read 63
__SYSCALL(__NR_read, sys_read)
#define __NR_write 64
__SYSCALL(__NR_write, sys_write)
最终预编译之后的结果应该像下面的样子是,我猜的:
void *sys_call_table[__NR_syscalls] = {
[63]=sys_read,
[64]=sys_read
下面我们花点宝贵的时间来验证下:
gcc -E ./main.c > pre.txt
我们只是预编译,看下输出:
void *sys_call_table[100] = {
# 1 "./systemcall.h" 1
[63] = (sys_read),
[64] = (sys_write),
# 12 "./main.c" 2
};
int main()
{
for(;;);
return 0;
}
与当初预想的一致。
优点:
0 : 节省了输入字符的时间:)
1: sys_call_table的填充时候,
可以避免索引号与函数指针不匹配的问题(前提是头文件没有写错)
2: 能让编译器去做的时候,当然比让人工去保证可靠
缺点:
代码的可阅读性减低很多
参考:kernel/arch/score/kernel/sys_call_table.c
(其实很多地方也有用到,如kill命令的实现,android解析init.rc文件的时候)