室友xin總結的Linux Kenel中關於C的一些有趣的語法,大部分是gcc的擴展,狂贊。特轉貼出來。 原文出處http://bbs.chinaunix.net/viewthread.php?tid=925106
原文如下:
經常從kernel裏面抄代碼,見到一些非常有趣的語法。我已經忘了它們位於哪些文件,但我記得它們的用法,就寫了一些小例子,放出來和大家分享一下,很好玩的。
我沒有去深究這些語法的出處,或許是gcc特有的,或許是C標準有的, 請知道的朋友點評。
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.結構體有名初始化
// 這我知道是c99標準裏面有的,因爲linux社區稱它爲“醜陋的”:lol:
struct
{
int i;
int j;
} ex = { .i = 10,
.j = 100};
3. 數組有名初始化
// 當時在寫這個數組的時候,我一直爲哪個字符在數組裏排第幾號煩惱
// 後來改成這種有名數組賦值就方便了
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.一次給數組中所有元素賦初值
int a[100] = {[0 ... 99] = 10};
5. 語句塊返回值
//這只能在IA64平臺(或許其他平臺也行)才能得到正確的值。它是通過mix指令實現的。
struct st { int c; int d; };
struct st test()
{
int a = 1;
int b = 1;
return ((struct st){a,b});
}
6. 把宏寫的像函數一樣
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書籍中看到。