GNC CC 是一個(gè)功能非常強大的跨平臺 C 編譯器,它對 C 語(yǔ)言提供了很多擴展, qe7Linux聯(lián)盟
這些擴展對優(yōu)化、目標代碼布局、更安全的檢查等方面提供了很強的支持。本文把 qe7Linux聯(lián)盟
支持 GNU 擴展的 C 語(yǔ)言稱(chēng)為 GNU C。 qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
Linux 內核代碼使用了大量的 GNU C 擴展,以至于能夠編譯 Linux 內核的唯一編 qe7Linux聯(lián)盟
譯器是 GNU CC,以前甚至出現過(guò)編譯 Linux 內核要使用特殊的 GNU CC 版本的情 qe7Linux聯(lián)盟
況。本文是對 Linux 內核使用的 GNU C 擴展的一個(gè)匯總,希望當你讀內核源碼遇 qe7Linux聯(lián)盟
到不理解的語(yǔ)法和語(yǔ)義時(shí),能從本文找到一個(gè)初步的解答,更詳細的信息可以查看 qe7Linux聯(lián)盟
gcc.info。文中的例子取自 Linux 2.4.18。 qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
語(yǔ)句表達式 qe7Linux聯(lián)盟
========== qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
GNU C 把包含在括號中的復合語(yǔ)句看做是一個(gè)表達式,稱(chēng)為語(yǔ)句表達式,它可以出 qe7Linux聯(lián)盟
現在任何允許表達式的地方,你可以在語(yǔ)句表達式中使用循環(huán)、局部變量等,原本 qe7Linux聯(lián)盟
只能在復合語(yǔ)句中使用。例如: qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
++++ include/linux/kernel.h qe7Linux聯(lián)盟
159: #define min_t(type,x,y) qe7Linux聯(lián)盟
160: ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) qe7Linux聯(lián)盟
++++ net/ipv4/tcp_output.c qe7Linux聯(lián)盟
654: int full_space = min_t(int, tp->window_clamp, tcp_full_space(sk)); qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
復合語(yǔ)句的最后一個(gè)語(yǔ)句應該是一個(gè)表達式,它的值將成為這個(gè)語(yǔ)句表達式的值。 qe7Linux聯(lián)盟
這里定義了一個(gè)安全的求最小值的宏,在標準 C 中,通常定義為: qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
#define min(x,y) ((x) < (y) ? (x) : (y)) qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
這個(gè)定義計算 x 和 y 分別兩次,當參數有副作用時(shí),將產(chǎn)生不正確的結果,使用 qe7Linux聯(lián)盟
語(yǔ)句表達式只計算參數一次,避免了可能的錯誤。語(yǔ)句表達式通常用于宏定義。 qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
Typeof qe7Linux聯(lián)盟
====== qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
使用前一節定義的宏需要知道參數的類(lèi)型,利用 typeof 可以定義更通用的宏,不 qe7Linux聯(lián)盟
必事先知道參數的類(lèi)型,例如: qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
++++ include/linux/kernel.h qe7Linux聯(lián)盟
141: #define min(x,y) ({ qe7Linux聯(lián)盟
142: const typeof(x) _x = (x); qe7Linux聯(lián)盟
143: const typeof(y) _y = (y); qe7Linux聯(lián)盟
144: (void) (&_x == &_y); qe7Linux聯(lián)盟
145: _x < _y ? _x : _y; }) qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
這里 typeof(x) 表示 x 的值類(lèi)型,第 142 行定義了一個(gè)與 x 類(lèi)型相同的局部變 qe7Linux聯(lián)盟
量 _x 并初使化為 x,注意第 144 行的作用是檢查參數 x 和 y 的類(lèi)型是否相同。 qe7Linux聯(lián)盟
typeof 可以用在任何類(lèi)型可以使用的地方,通常用于宏定義。 qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
零長(cháng)度數組 qe7Linux聯(lián)盟
========== qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
GNU C 允許使用零長(cháng)度數組,在定義變長(cháng)對象的頭結構時(shí),這個(gè)特性非常有用。例 qe7Linux聯(lián)盟
如: qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
++++ include/linux/minix_fs.h qe7Linux聯(lián)盟
85: struct minix_dir_entry { qe7Linux聯(lián)盟
86: __u16 inode; qe7Linux聯(lián)盟
87: char name[0]; qe7Linux聯(lián)盟
88: }; qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
結構的最后一個(gè)元素定義為零長(cháng)度數組,它不占結構的空間。在標準 C 中則需要 qe7Linux聯(lián)盟
定義數組長(cháng)度為 1,分配時(shí)計算對象大小比較復雜。 qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
可變參數宏 qe7Linux聯(lián)盟
========== qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
在 GNU C 中,宏可以接受可變數目的參數,就象函數一樣,例如: qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
++++ include/linux/kernel.h qe7Linux聯(lián)盟
110: #define pr_debug(fmt,arg...) qe7Linux聯(lián)盟
111: printk(KERN_DEBUG fmt,##arg) qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
這里 arg 表示其余的參數,可以是零個(gè)或多個(gè),這些參數以及參數之間的逗號構 qe7Linux聯(lián)盟
成 arg 的值,在宏擴展時(shí)替換 arg,例如: qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
pr_debug("%s:%d",filename,line) qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
擴展為 qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
printk("<7>" "%s:%d", filename, line) qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
使用 ## 的原因是處理 arg 不匹配任何參數的情況,這時(shí) arg 的值為空,GNU qe7Linux聯(lián)盟
C 預處理器在這種特殊情況下,丟棄 ## 之前的逗號,這樣 qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
pr_debug("success!n") qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
擴展為 qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
printk("<7>" "success!n") qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
注意最后沒(méi)有逗號。 qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
標號元素 qe7Linux聯(lián)盟
======== qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
標準 C 要求數組或結構變量的初使化值必須以固定的順序出現,在 GNU C 中,通 qe7Linux聯(lián)盟
過(guò)指定索引或結構域名,允許初始化值以任意順序出現。指定數組索引的方法是在 qe7Linux聯(lián)盟
初始化值前寫(xiě) '[INDEX] =',要指定一個(gè)范圍使用 '[FIRST ... LAST] =' 的形式, qe7Linux聯(lián)盟
例如: qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
+++++ arch/i386/kernel/irq.c qe7Linux聯(lián)盟
1079: static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL }; qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
將數組的所有元素初使化為 ~0UL,這可以看做是一種簡(jiǎn)寫(xiě)形式。 qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
要指定結構元素,在元素值前寫(xiě) 'FIELDNAME:',例如: qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
++++ fs/ext2/file.c qe7Linux聯(lián)盟
41: struct file_operations ext2_file_operations = { qe7Linux聯(lián)盟
42: llseek: generic_file_llseek, qe7Linux聯(lián)盟
43: read: generic_file_read, qe7Linux聯(lián)盟
44: write: generic_file_write, qe7Linux聯(lián)盟
45: ioctl: ext2_ioctl, qe7Linux聯(lián)盟
46: mmap: generic_file_mmap, qe7Linux聯(lián)盟
47: open: generic_file_open, qe7Linux聯(lián)盟
48: release: ext2_release_file, qe7Linux聯(lián)盟
49: fsync: ext2_sync_file, qe7Linux聯(lián)盟
50 }; qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
將結構 ext2_file_operations 的元素 llseek 初始化為 generic_file_llseek, qe7Linux聯(lián)盟
元素 read 初始化為 genenric_file_read,依次類(lèi)推。我覺(jué)得這是 GNU C 擴展中 qe7Linux聯(lián)盟
最好的特性之一,當結構的定義變化以至元素的偏移改變時(shí),這種初始化方法仍然 qe7Linux聯(lián)盟
保證已知元素的正確性。對于未出現在初始化中的元素,其初值為 0。 qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
Case 范圍 qe7Linux聯(lián)盟
========= qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
GNU C 允許在一個(gè) case 標號中指定一個(gè)連續范圍的值,例如: qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
++++ arch/i386/kernel/irq.c qe7Linux聯(lián)盟
1062: case '0' ... '9': c -= '0'; break; qe7Linux聯(lián)盟
1063: case 'a' ... 'f': c -= 'a'-10; break; qe7Linux聯(lián)盟
1064: case 'A' ... 'F': c -= 'A'-10; break; qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
case '0' ... '9': qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
相當于 qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
case '0': case '1': case '2': case '3': case '4': qe7Linux聯(lián)盟
case '5': case '6': case '7': case '8': case '9': qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
聲明的特殊屬性 qe7Linux聯(lián)盟
============== qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
GNU C 允許聲明函數、變量和類(lèi)型的特殊屬性,以便手工的代碼優(yōu)化和更仔細的代 qe7Linux聯(lián)盟
碼檢查。要指定一個(gè)聲明的屬性,在聲明后寫(xiě) qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
__attribute__ (( ATTRIBUTE )) qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
其中 ATTRIBUTE 是屬性說(shuō)明,多個(gè)屬性以逗號分隔。GNU C 支持十幾個(gè)屬性,這 qe7Linux聯(lián)盟
里介紹最常用的: qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
* noreturn qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
屬性 noreturn 用于函數,表示該函數從不返回。這可以讓編譯器生成稍微優(yōu)化的 qe7Linux聯(lián)盟
代碼,最重要的是可以消除不必要的警告信息比如未初使化的變量。例如: qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
++++ include/linux/kernel.h qe7Linux聯(lián)盟
47: # define ATTRIB_NORET __attribute__((noreturn)) qe7Linux聯(lián)盟
.... qe7Linux聯(lián)盟
61: asmlinkage NORET_TYPE void do_exit(long error_code) qe7Linux聯(lián)盟
ATTRIB_NORET; qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
* format (ARCHETYPE, STRING-INDEX, FIRST-TO-CHECK) qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
屬性 format 用于函數,表示該函數使用 printf, scanf 或 strftime 風(fēng)格的參 qe7Linux聯(lián)盟
數,使用這類(lèi)函數最容易犯的錯誤是格式串與參數不匹配,指定 format 屬性可以 qe7Linux聯(lián)盟
讓編譯器根據格式串檢查參數類(lèi)型。例如: qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
++++ include/linux/kernel.h? qe7Linux聯(lián)盟
89: asmlinkage int printk(const char * fmt, ...) qe7Linux聯(lián)盟
90: __attribute__ ((format (printf, 1, 2))); qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
表示第一個(gè)參數是格式串,從第二個(gè)參數起根據格式串檢查參數。 qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
* unused qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
屬性 unused 用于函數和變量,表示該函數或變量可能不使用,這個(gè)屬性可以避免 qe7Linux聯(lián)盟
編譯器產(chǎn)生警告信息。 qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
* section ("section-name") qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
屬性 section 用于函數和變量,通常編譯器將函數放在 .text 節,變量放在 qe7Linux聯(lián)盟
.data 或 .bss 節,使用 section 屬性,可以讓編譯器將函數或變量放在指定的 qe7Linux聯(lián)盟
節中。例如: qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
++++ include/linux/init.h qe7Linux聯(lián)盟
78: #define __init __attribute__ ((__section__ (".text.init"))) qe7Linux聯(lián)盟
79: #define __exit __attribute__ ((unused, __section__(".text.exit"))) qe7Linux聯(lián)盟
80: #define __initdata __attribute__ ((__section__ (".data.init"))) qe7Linux聯(lián)盟
81: #define __exitdata __attribute__ ((unused, __section__ (".data.exit"))) qe7Linux聯(lián)盟
82: #define __initsetup __attribute__ ((unused,__section__ (".setup.init"))) qe7Linux聯(lián)盟
83: #define __init_call __attribute__ ((unused,__section__ (".initcall.init"))) qe7Linux聯(lián)盟
84: #define __exit_call __attribute__ ((unused,__section__ (".exitcall.exit"))) qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
連接器可以把相同節的代碼或數據安排在一起,Linux 內核很喜歡使用這種技術(shù), qe7Linux聯(lián)盟
例如系統的初始化代碼被安排在單獨的一個(gè)節,在初始化結束后就可以釋放這部分 qe7Linux聯(lián)盟
內存。 qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
* aligned (ALIGNMENT) qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
屬性 aligned 用于變量、結構或聯(lián)合類(lèi)型,指定變量、結構域、結構或聯(lián)合的對 qe7Linux聯(lián)盟
齊量,以字節為單位,例如: qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
++++ include/asm-i386/processor.h qe7Linux聯(lián)盟
294: struct i387_fxsave_struct { qe7Linux聯(lián)盟
295: unsigned short cwd; qe7Linux聯(lián)盟
296: unsigned short swd; qe7Linux聯(lián)盟
297: unsigned short twd; qe7Linux聯(lián)盟
298: unsigned short fop; qe7Linux聯(lián)盟
299: long fip; qe7Linux聯(lián)盟
300: long fcs; qe7Linux聯(lián)盟
301: long foo; qe7Linux聯(lián)盟
...... qe7Linux聯(lián)盟
308: } __attribute__ ((aligned (16))); qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
表示該結構類(lèi)型的變量以 16 字節對齊。通常編譯器會(huì )選擇合適的對齊量,顯示指 qe7Linux聯(lián)盟
定對齊通常是由于體系限制、優(yōu)化等原因。 qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
* packed qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
屬性 packed 用于變量和類(lèi)型,用于變量或結構域時(shí)表示使用最小可能的對齊,用 qe7Linux聯(lián)盟
于枚舉、結構或聯(lián)合類(lèi)型時(shí)表示該類(lèi)型使用最小的內存。例如: qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
++++ include/asm-i386/desc.h qe7Linux聯(lián)盟
51: struct Xgt_desc_struct { qe7Linux聯(lián)盟
52: unsigned short size; qe7Linux聯(lián)盟
53: unsigned long address __attribute__((packed)); qe7Linux聯(lián)盟
54: }; qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
域 address 將緊接著(zhù) size 分配。屬性 packed 的用途大多是定義硬件相關(guān)的結 qe7Linux聯(lián)盟
構,使元素之間沒(méi)有因對齊而造成的空洞。 qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
當前函數名 qe7Linux聯(lián)盟
========== qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
GNU CC 預定義了兩個(gè)標志符保存當前函數的名字,__FUNCTION__ 保存函數在源碼 qe7Linux聯(lián)盟
中的名字,__PRETTY_FUNCTION__ 保存帶語(yǔ)言特色的名字。在 C 函數中,這兩個(gè) qe7Linux聯(lián)盟
名字是相同的,在 C++ 函數中,__PRETTY_FUNCTION__ 包括函數返回類(lèi)型等額外 qe7Linux聯(lián)盟
信息,Linux 內核只使用了 __FUNCTION__。 qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
++++ fs/ext2/super.c qe7Linux聯(lián)盟
98: void ext2_update_dynamic_rev(struct super_block *sb) qe7Linux聯(lián)盟
99: { qe7Linux聯(lián)盟
100: struct ext2_super_block *es = EXT2_SB(sb)->s_es; qe7Linux聯(lián)盟
101: qe7Linux聯(lián)盟
102: if (le32_to_cpu(es->s_rev_level) > EXT2_GOOD_OLD_REV) qe7Linux聯(lián)盟
103: return; qe7Linux聯(lián)盟
104: qe7Linux聯(lián)盟
105: ext2_warning(sb, __FUNCTION__, qe7Linux聯(lián)盟
106: "updating to rev %d because of new feature flag, " qe7Linux聯(lián)盟
107: "running e2fsck is recommended", qe7Linux聯(lián)盟
108: EXT2_DYNAMIC_REV); qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
這里 __FUNCTION__ 將被替換為字符串 "ext2_update_dynamic_rev"。雖然 qe7Linux聯(lián)盟
__FUNCTION__ 看起來(lái)類(lèi)似于標準 C 中的 __FILE__,但實(shí)際上 __FUNCTION__ qe7Linux聯(lián)盟
是被編譯器替換的,不象 __FILE__ 被預處理器替換。 qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
內建函數 qe7Linux聯(lián)盟
======== qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
GNU C 提供了大量的內建函數,其中很多是標準 C 庫函數的內建版本,例如 qe7Linux聯(lián)盟
memcpy,它們與對應的 C 庫函數功能相同,本文不討論這類(lèi)函數,其他內建函數 qe7Linux聯(lián)盟
的名字通常以 __builtin 開(kāi)始。 qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
* __builtin_return_address (LEVEL) qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
內建函數 __builtin_return_address 返回當前函數或其調用者的返回地址,參數 qe7Linux聯(lián)盟
LEVEL 指定在棧上搜索框架的個(gè)數,0 表示當前函數的返回地址,1 表示當前函數 qe7Linux聯(lián)盟
的調用者的返回地址,依此類(lèi)推。例如: qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
++++ kernel/sched.c qe7Linux聯(lián)盟
437: printk(KERN_ERR "schedule_timeout: wrong timeout " qe7Linux聯(lián)盟
438: "value %lx from %pn", timeout, qe7Linux聯(lián)盟
439: __builtin_return_address(0)); qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
* __builtin_constant_p(EXP) qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
內建函數 __builtin_constant_p 用于判斷一個(gè)值是否為編譯時(shí)常數,如果參數 qe7Linux聯(lián)盟
EXP 的值是常數,函數返回 1,否則返回 0。例如: qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
++++ include/asm-i386/bitops.h qe7Linux聯(lián)盟
249: #define test_bit(nr,addr) qe7Linux聯(lián)盟
250: (__builtin_constant_p(nr) ? qe7Linux聯(lián)盟
251: constant_test_bit((nr),(addr)) : qe7Linux聯(lián)盟
252: variable_test_bit((nr),(addr))) qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
很多計算或操作在參數為常數時(shí)有更優(yōu)化的實(shí)現,在 GNU C 中用上面的方法可以 qe7Linux聯(lián)盟
根據參數是否為常數,只編譯常數版本或非常數版本,這樣既不失通用性,又能在 qe7Linux聯(lián)盟
參數是常數時(shí)編譯出最優(yōu)化的代碼。 qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
* __builtin_expect(EXP, C) qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
內建函數 __builtin_expect 用于為編譯器提供分支預測信息,其返回值是整數表 qe7Linux聯(lián)盟
達式 EXP 的值,C 的值必須是編譯時(shí)常數。例如: qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
++++ include/linux/compiler.h qe7Linux聯(lián)盟
13: #define likely(x) __builtin_expect((x),1) qe7Linux聯(lián)盟
14: #define unlikely(x) __builtin_expect((x),0) qe7Linux聯(lián)盟
++++ kernel/sched.c qe7Linux聯(lián)盟
564: if (unlikely(in_interrupt())) { qe7Linux聯(lián)盟
565: printk("Scheduling in interruptn"); qe7Linux聯(lián)盟
566: BUG(); qe7Linux聯(lián)盟
567: } qe7Linux聯(lián)盟
qe7Linux聯(lián)盟
這個(gè)內建函數的語(yǔ)義是 EXP 的預期值是 C,編譯器可以根據這個(gè)信息適當地重排 qe7Linux聯(lián)盟
語(yǔ)句塊的順序,使程序在預期的情況下有更高的執行效率。上面的例子表示處于中 qe7Linux聯(lián)盟
斷上下文是很少發(fā)生的,第 565-566 行的目標碼可能會(huì )放在較遠的位置,以保證 qe7Linux聯(lián)盟
經(jīng)常執行的目標碼更緊湊
Linux聯(lián)盟收集整理 ,轉貼請標明原始鏈接,如有任何疑問(wèn)歡迎來(lái)本站
Linux論壇討論