Linux kernel中有趣的语法[zz]

室友xin总结的Linux Kenel中关于C的一些有趣的语法,大部分是gcc的扩展,狂赞。特转贴出来。 原文出处http://bbs.chinaunix.net/viewthread.php?tid=925106

原文如下:

经常从kernel里面抄代码,见到一些非常有趣的语法。我已经忘了它们位于哪些文件,但我记得它们的用法,就写了一些小例子,放出来和大家分享一下,很好玩的。
我没有去深究这些语法的出处,或许是gcc特有的,或许是C标准有的, 请知道的朋友点评。

1.算偏移 

CODE:
// 1. 先来个最常见的,算偏移
struct ex
{
    char a[100];
    int b;
    long c;
    char d;
};

#define OFFSET(x) ((unsigned long)(&((struct ex *)0)->x))

/*
   通过这种方法来计算每个元素在结构体里的偏移量是很方便的。特别是在写汇编程序的时候,这种自动得到偏移量的方法省去了程序员许多功夫。 通常的做法是把你想要知道的所有偏移量通过宏写到一个.c文件中,在编译时自动生成.h文件供汇编文件引用。
*/

 Comments:参考Linux kernel 里面list_head的源程序

 2.结构体有名初始化

CODE:
// 也是很常见的,结构体有名初始化。
// 这我知道是c99标准里面有的,因为linux社区称它为“丑陋的”:lol:

struct   
{
    int i;
    int j;
} ex = { .i = 10,
         .j = 100};


 3. 数组有名初始化

CODE:
// 数组有名初始化
// 当时在写这个数组的时候,我一直为哪个字符在数组里排第几号烦恼
// 后来改成这种有名数组赋值就方便了

static char *ivt_vector[] =
{
    [0] = "vmx_vhpt_miss", [1] = "vmx_itlb_miss",
    [2] = "vmx_dtlb_miss", [3] = "vmx_alt_itlb_miss",
    [4] = "vmx_alt_dtlb_miss", [5] = "vmx_nested_dtlb_miss",
    [6] = "vmx_ikey_miss", [7] = "vmx_dkey_miss",
    [8] = "vmx_dirty_bit", [9] = "vmx_iaccess_bit",
    [10] = "vmx_daccess_bit", [11] = "vmx_break_fault",
    [12] = "vmx_interrupt", [13] = "vmx_virtual_exirq",
    [14] = "ia64_hypercall_setup", [15] = "reserved",
    [16] = "reserved", [17] = "reserved",
    [18] = "reserved", [19] = "reserved",
    [20] = "vmx_page_not_present", [21] = "vmx_key_permission",
    [22] = "vmx_iaccess_rights", [23] = "vmx_daccess_rights",
    [24] = "vmx_general_exception", [25] = "vmx_disabled_fp_reg",
    [26] = "vmx_nat_consumption", [27] = "vmx_speculation_vector",
    [28] = "reserved", [29] = "vmx_debug_vector",
    [30] = "vmx_unaligned_access", [31] = "vmx_unsupported_data_reference",
    [32] = "vmx_floating_point_fault", [33] = "vmx_floating_point_trap",
    [34] = "vmx_lower_privilege_trap", [35] = "vmx_taken_branch_trap",
    [36] = "vmx_single_step_trap", [37] = "vmx_virtualization_fault",
    [38] = "reserved",[39] = "reserved", [40] = "reserved",
    "reserved","reserved","reserved","reserved" "reserved",
    "reserved","reserved","reserved","reserved","reserved",
    "reserved","reserved","reserved","reserved","reserved",
    "reserved","reserved","reserved","reserved","reserved",
    "reserved","reserved","reserved","reserved","reserved",
    "reserved","reserved","reserved","reserved",
};


4.一次给数组中所有元素赋初值

CODE:
// 一次给数组中所有元素赋初值

int a[100] = {[0 ... 99] = 10};


 5. 语句块返回值

CODE:
// 语句块返回值
//这只能在IA64平台(或许其他平台也行)才能得到正确的值。它是通过mix指令实现的。

struct st { int  c; int d; };
struct st test()
{
    int a = 1;
    int b = 1;

    return ((struct st){a,b});
}

6. 把宏写的像函数一样

CODE:
//把宏写的像函数一样


struct ex
{
    int i;
    int j;
} ex1 = { .i = 10,
         .j = 100};

#define v(a,b) ({struct ex t; /
                if ( a > b )    /
                    t.i = a;    /
                else        /
                    t.i = b;    /
                    t;})

int main()
{
    printf("%d/n", v(1,2).i);
    printf("%d/n", v(3,2).i);
}
呵呵,是不是都很很有趣
其他的诸如typeof、attributes就很普通了,大家经常能在各种linux书籍中看到。
 

 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值