.. include:: ../disclaimer-zh_CN.rst :Original: :ref:`Documentation/process/coding-style.rst <codingstyle>` .. _cn_codingstyle: è¯è :: ä¸æçç»´æ¤è ï¼ å¼ ä¹ Zhang Le <r0bertz@gentoo.org> ä¸æçç¿»è¯è ï¼ å¼ ä¹ Zhang Le <r0bertz@gentoo.org> ä¸æçæ ¡è¯è ï¼ çèª Wang Cong <xiyou.wangcong@gmail.com> wheelz <kernel.zeng@gmail.com> 管æä¸ Xudong Guan <xudong.guan@gmail.com> Li Zefan <lizf@cn.fujitsu.com> Wang Chen <wangchen@cn.fujitsu.com> Linux å æ ¸ä»£ç é£æ ¼ ========================= è¿æ¯ä¸ä¸ªç®ççææ¡£ï¼æè¿°äº linux å æ ¸çé¦é代ç é£æ ¼ã代ç é£æ ¼æ¯å 人èå¼çï¼ èä¸æä¸æ¿ææèªå·±çè§ç¹å¼ºå ç»ä»»ä½äººï¼ä½è¿å°±åæå»åä»»ä½äºæ é½å¿ é¡»éµå¾ªçåå é£æ ·ï¼æä¹å¸æå¨ç»å¤§å¤æ°äºä¸ä¿æè¿ç§çæ度ã请 (å¨å代ç æ¶) è³å°èèä¸ä¸è¿é ç代ç é£æ ¼ã é¦å ï¼æå»ºè®®ä½ æå°ä¸ä»½ GNU 代ç è§èï¼ç¶åä¸è¦è¯»ãç§äºå®ï¼è¿æ¯ä¸ä¸ªå ·æéå¤§è±¡å¾ æ§æä¹çå¨ä½ã ä¸ç®¡ææ ·ï¼ç°å¨æ们å¼å§ï¼ 1) ç¼©è¿ -------------- å¶è¡¨ç¬¦æ¯ 8 个å符ï¼æ以缩è¿ä¹æ¯ 8 个å符ãæäºå¼ç«¯è¿å¨è¯å¾å°ç¼©è¿å为 4 (çè³ 2ï¼) å符深ï¼è¿å ä¹ç¸å½äºå°è¯å°åå¨ççå¼å®ä¹ä¸º 3ã çç±ï¼ç¼©è¿çå ¨é¨æä¹å°±å¨äºæ¸ æ¥çå®ä¹ä¸ä¸ªæ§å¶åèµ·æ¢äºä½å¤ãå°¤å ¶æ¯å½ä½ ç¯çä½ ç å±å¹è¿ç»çäº 20 å°æ¶ä¹åï¼ä½ å°ä¼åç°å¤§ä¸ç¹ç缩è¿ä¼ä½¿ä½ æ´å®¹æå辨缩è¿ã ç°å¨ï¼æäºäººä¼æ±æ¨ 8 个å符ç缩è¿ä¼ä½¿ä»£ç åå³è¾¹ç§»å¨ç太è¿ï¼å¨ 80 个å符çç»ç«¯ å±å¹ä¸å°±å¾é¾è¯»è¿æ ·ç代ç ãè¿ä¸ªé®é¢ççæ¡æ¯ï¼å¦æä½ éè¦ 3 级以ä¸ç缩è¿ï¼ä¸ç®¡ç¨ ä½ç§æ¹å¼ä½ ç代ç å·²ç»æé®é¢äºï¼åºè¯¥ä¿®æ£ä½ çç¨åºã ç®èè¨ä¹ï¼8 个å符ç缩è¿å¯ä»¥è®©ä»£ç æ´å®¹æé 读ï¼è¿æä¸ä¸ªå¥½å¤æ¯å½ä½ çå½æ°åµå¥å¤ª æ·±çæ¶åå¯ä»¥ç»ä½ è¦åãçå¿è¿ä¸ªè¦åã å¨ switch è¯å¥ä¸æ¶é¤å¤çº§ç¼©è¿çé¦éçæ¹å¼æ¯è®© ``switch`` åä»å±äºå®ç ``case`` æ ç¾å¯¹é½äºåä¸åï¼èä¸è¦ ``两次缩è¿`` ``case`` æ ç¾ãæ¯å¦ï¼ .. code-block:: c switch (suffix) { case 'G': case 'g': mem <<= 30; break; case 'M': case 'm': mem <<= 20; break; case 'K': case 'k': mem <<= 10; /* fall through */ default: break; } ä¸è¦æå¤ä¸ªè¯å¥æ¾å¨ä¸è¡éï¼é¤éä½ æä»ä¹ä¸è¥¿è¦éèï¼ .. code-block:: c if (condition) do_this; do_something_everytime; ä¹ä¸è¦å¨ä¸è¡éæ¾å¤ä¸ªèµå¼è¯å¥ãå æ ¸ä»£ç é£æ ¼è¶ 级ç®åãå°±æ¯é¿å å¯è½å¯¼è´å«äººè¯¯è¯» ç表达å¼ã é¤äºæ³¨éãææ¡£å Kconfig ä¹å¤ï¼ä¸è¦ä½¿ç¨ç©ºæ ¼æ¥ç¼©è¿ï¼åé¢çä¾åæ¯ä¾å¤ï¼æ¯ææ为 ä¹ã éç¨ä¸ä¸ªå¥½çç¼è¾å¨ï¼ä¸è¦å¨è¡å°¾çç©ºæ ¼ã 2) æé¿çè¡åå符串ææ£ ------------------------------ 代ç é£æ ¼çæä¹å°±å¨äºä½¿ç¨å¹³å¸¸ä½¿ç¨çå·¥å ·æ¥ç»´æ代ç çå¯è¯»æ§åå¯ç»´æ¤æ§ã æ¯ä¸è¡çé¿åº¦çéå¶æ¯ 80 åï¼æ们强ç建议æ¨éµå®è¿ä¸ªæ¯ä¾ã é¿äº 80 åçè¯å¥è¦ææ£æææä¹çç段ãé¤éè¶ è¿ 80 åè½æ¾èå¢å å¯è¯»æ§ï¼å¹¶ä¸ä¸ ä¼éèä¿¡æ¯ãåç段è¦ææ¾çäºæ¯ç段ï¼å¹¶ææ¾é å³ãè¿åæ ·éç¨äºæçå¾é¿åæ°å表 çå½æ°å¤´ãç¶èï¼ç»å¯¹ä¸è¦ææ£å¯¹ç¨æ·å¯è§çå符串ï¼ä¾å¦ printk ä¿¡æ¯ï¼å 为è¿æ ·å°± å¾é¾å¯¹å®ä»¬ grepã 3) 大æ¬å·åç©ºæ ¼çæ¾ç½® ------------------------------ C è¯è¨é£æ ¼ä¸å¦å¤ä¸ä¸ªå¸¸è§é®é¢æ¯å¤§æ¬å·çæ¾ç½®ãå缩è¿å¤§å°ä¸åï¼éæ©æå¼ç¨æç§æ¾ ç½®çç¥å¹¶æ²¡æå¤å°ææ¯ä¸çåå ï¼ä¸è¿é¦éçæ¹å¼ï¼å°±å Kernighan å Ritchie å±ç¤º ç»æ们çï¼æ¯æèµ·å§å¤§æ¬å·æ¾å¨è¡å°¾ï¼èæç»æ大æ¬å·æ¾å¨è¡é¦ï¼æä»¥ï¼ .. code-block:: c if (x is true) { we do y } è¿éç¨äºææçéå½æ°è¯å¥å (if, switch, for, while, do)ãæ¯å¦ï¼ .. code-block:: c switch (action) { case KOBJ_ADD: return "add"; case KOBJ_REMOVE: return "remove"; case KOBJ_CHANGE: return "change"; default: return NULL; } ä¸è¿ï¼æä¸ä¸ªä¾å¤ï¼é£å°±æ¯å½æ°ï¼å½æ°çèµ·å§å¤§æ¬å·æ¾ç½®äºä¸ä¸è¡çå¼å¤´ï¼æä»¥ï¼ .. code-block:: c int function(int x) { body of function } å ¨ä¸ççå¼ç«¯å¯è½ä¼æ±æ¨è¿ä¸ªä¸ä¸è´æ§æ¯... å... ä¸ä¸è´çï¼ä¸è¿æææç»´å¥å ¨ç人 é½ç¥é (a) K&R æ¯ **æ£ç¡®ç** å¹¶ä¸ (b) K&R æ¯æ£ç¡®çãæ¤å¤ï¼ä¸ç®¡ææ ·å½æ°é½æ¯ç¹ æ®ç (C å½æ°æ¯ä¸è½åµå¥ç)ã 注æç»æ大æ¬å·ç¬èªå æ®ä¸è¡ï¼é¤éå®åé¢è·çåä¸ä¸ªè¯å¥çå©ä½é¨åï¼ä¹å°±æ¯ do è¯ å¥ä¸ç "while" æè if è¯å¥ä¸ç "else"ï¼åè¿æ ·ï¼ .. code-block:: c do { body of do-loop } while (condition); å .. code-block:: c if (x == y) { .. } else if (x > y) { ... } else { .... } çç±ï¼K&Rã ä¹è¯·æ³¨æè¿ç§å¤§æ¬å·çæ¾ç½®æ¹å¼ä¹è½ä½¿ç©º (æè å·®ä¸å¤ç©ºç) è¡çæ°éæå°åï¼åæ¶ä¸ 失å¯è¯»æ§ãå æ¤ï¼ç±äºä½ çå±å¹ä¸çæ°è¡æ¯ä¸å¯åçèµæº (æ³æ³ 25 è¡çç»ç«¯å±å¹)ï¼ä½ å°ä¼ææ´å¤ç空è¡æ¥æ¾ç½®æ³¨éã å½åªæä¸ä¸ªåç¬çè¯å¥çæ¶åï¼ä¸ç¨å ä¸å¿ è¦ç大æ¬å·ã .. code-block:: c if (condition) action(); å .. code-block:: c if (condition) do_this(); else do_that(); è¿å¹¶ä¸éç¨äºåªæä¸ä¸ªæ¡ä»¶åæ¯æ¯åè¯å¥çæ åµï¼è¿æ¶ææåæ¯é½è¦ä½¿ç¨å¤§æ¬å·ï¼ .. code-block:: c if (condition) { do_this(); do_that(); } else { otherwise(); } 3.1) ç©ºæ ¼ ******************** Linux å æ ¸çç©ºæ ¼ä½¿ç¨æ¹å¼ (主è¦) åå³äºå®æ¯ç¨äºå½æ°è¿æ¯å ³é®åã(大å¤æ°) å ³é®å åè¦å ä¸ä¸ªç©ºæ ¼ãå¼å¾æ³¨æçä¾å¤æ¯ sizeof, typeof, alignof å __attribute__ï¼è¿ äºå ³é®åæäºç¨åº¦ä¸çèµ·æ¥æ´åå½æ° (å®ä»¬å¨ Linux éä¹å¸¸å¸¸ä¼´éå°æ¬å·è使ç¨ï¼å°½ç®¡ å¨ C éè¿æ ·çå°æ¬å·ä¸æ¯å¿ éçï¼å°±å ``struct fileinfo info;`` 声æè¿åç ``sizeof info``)ã æ以å¨è¿äºå ³é®åä¹åæ¾ä¸ä¸ªç©ºæ ¼:: if, switch, case, for, do, while ä½æ¯ä¸è¦å¨ sizeof, typeof, alignof æè __attribute__ è¿äºå ³é®åä¹åæ¾ç©ºæ ¼ã ä¾å¦ï¼ .. code-block:: c s = sizeof(struct file); ä¸è¦å¨å°æ¬å·éç表达å¼ä¸¤ä¾§å ç©ºæ ¼ãè¿æ¯ä¸ä¸ª **åä¾** ï¼ .. code-block:: c s = sizeof( struct file ); å½å£°ææéç±»åæè è¿åæéç±»åçå½æ°æ¶ï¼ ``*`` çé¦é使ç¨æ¹å¼æ¯ä½¿ä¹é è¿åéå æè å½æ°åï¼èä¸æ¯é è¿ç±»ååãä¾åï¼ .. code-block:: c char *linux_banner; unsigned long long memparse(char *ptr, char **retptr); char *match_strdup(substring_t *s); å¨å¤§å¤æ°äºå åä¸å æä½ç¬¦ä¸¤ä¾§ä½¿ç¨ä¸ä¸ªç©ºæ ¼ï¼ä¾å¦ä¸é¢ææè¿äºæä½ç¬¦:: = + - < > * / % | & ^ <= >= == != ? : ä½æ¯ä¸å æä½ç¬¦åä¸è¦å ç©ºæ ¼:: & * + - ~ ! sizeof typeof alignof __attribute__ defined åç¼èªå åèªåä¸å æä½ç¬¦åä¸å ç©ºæ ¼:: ++ -- åç¼èªå åèªåä¸å æä½ç¬¦åä¸å ç©ºæ ¼:: ++ -- ``.`` å ``->`` ç»æä½æåæä½ç¬¦ååä¸å ç©ºæ ¼ã ä¸è¦å¨è¡å°¾ç空ç½ãæäºå¯ä»¥èªå¨ç¼©è¿çç¼è¾å¨ä¼å¨æ°è¡çè¡é¦å å ¥ééç空ç½ï¼ç¶å ä½ å°±å¯ä»¥ç´æ¥å¨é£ä¸è¡è¾å ¥ä»£ç ãä¸è¿åå¦ä½ æå没æå¨é£ä¸è¡è¾å ¥ä»£ç ï¼æäºç¼è¾å¨ å°±ä¸ä¼ç§»é¤å·²ç»å å ¥ç空ç½ï¼å°±åä½ æ æçä¸ä¸ä¸ªåªæ空ç½çè¡ãå å«è¡å°¾ç©ºç½çè¡å°± è¿æ ·äº§çäºã å½ git åç°è¡¥ä¸å å«äºè¡å°¾ç©ºç½çæ¶åä¼è¦åä½ ï¼å¹¶ä¸å¯ä»¥åºä½ çè¦æ±å»æè¡å°¾ç©ºç½ï¼ ä¸è¿å¦æä½ æ¯æ£å¨æä¸ç³»åè¡¥ä¸ï¼è¿æ ·åä¼å¯¼è´åé¢çè¡¥ä¸å¤±è´¥ï¼å ä¸ºä½ æ¹åäºè¡¥ä¸ç ä¸ä¸æã 4) å½å ------------------------------ C æ¯ä¸ä¸ªç®æ´çè¯è¨ï¼ä½ çå½åä¹åºè¯¥è¿æ ·ãå Modula-2 å Pascal ç¨åºåä¸åï¼ C ç¨åºåä¸ä½¿ç¨ç±»ä¼¼ ThisVariableIsATemporaryCounter è¿æ ·å丽çååãC ç¨åºåä¼ ç§°é£ä¸ªåé为 ``tmp`` ï¼è¿æ ·åèµ·æ¥ä¼æ´å®¹æï¼èä¸è³å°ä¸ä¼ä»¤å ¶é¾äºç解ã ä¸è¿ï¼è½ç¶æ··ç¨å¤§å°åçååæ¯ä¸æå¡ä½¿ç¨çï¼ä½æ¯å ¨å±åéè¿æ¯éè¦ä¸ä¸ªå ·æè¿°æ§ç ååã称ä¸ä¸ªå ¨å±å½æ°ä¸º ``foo`` æ¯ä¸ä¸ªé¾ä»¥é¥¶æçé误ã å ¨å±åé (åªæå½ä½ **çæ£** éè¦å®ä»¬çæ¶ååç¨å®) éè¦æä¸ä¸ªå ·æè¿°æ§çååï¼å°± åå ¨å±å½æ°ãå¦æä½ æä¸ä¸ªå¯ä»¥è®¡ç®æ´»å¨ç¨æ·æ°éçå½æ°ï¼ä½ åºè¯¥å«å® ``count_active_users()`` æè 类似çååï¼ä½ ä¸åºè¯¥å«å® ``cntuser()`` ã å¨å½æ°åä¸å å«å½æ°ç±»å (æè°çåçå©å½åæ³) æ¯èååºäºé®é¢ââç¼è¯å¨ç¥éé£äºç±» åèä¸è½å¤æ£æ¥é£äºç±»åï¼è¿æ ·ååªè½æç¨åºåå¼ç³æ¶äºãé¾æªå¾®è½¯æ»æ¯å¶é åºæé®é¢ çç¨åºã æ¬å°åéååºè¯¥ç®çï¼èä¸è½å¤è¡¨è¾¾ç¸å ³çå«ä¹ãå¦æä½ æä¸äºéæºçæ´æ°åç循ç¯è®¡ æ°å¨ï¼å®åºè¯¥è¢«ç§°ä¸º ``i`` ãå«å® ``loop_counter`` 并æ çå¤ï¼å¦æå®æ²¡æ被误解ç å¯è½çè¯ã类似çï¼ ``tmp`` å¯ä»¥ç¨æ¥ç§°å¼ä»»æç±»åç临æ¶åéã å¦æä½ ææ··æ·äºä½ çæ¬å°åéåï¼ä½ å°±éå°å¦ä¸ä¸ªé®é¢äºï¼å«åå½æ°å¢é¿è·å°è失衡综 åçã请ç第å ç« (å½æ°)ã 5) Typedef ----------- ä¸è¦ä½¿ç¨ç±»ä¼¼ ``vps_t`` ä¹ç±»çä¸è¥¿ã 对ç»æä½åæéä½¿ç¨ typedef æ¯ä¸ä¸ª **é误** ãå½ä½ å¨ä»£ç éçå°ï¼ .. code-block:: c vps_t a; è¿ä»£è¡¨ä»ä¹ææå¢ï¼ ç¸åï¼å¦ææ¯è¿æ · .. code-block:: c struct virtual_container *a; ä½ å°±ç¥é ``a`` æ¯ä»ä¹äºã å¾å¤äººè®¤ä¸º typedef ``è½æé«å¯è¯»æ§`` ãå®é ä¸æ¯è¿æ ·çãå®ä»¬åªå¨ä¸åæ åµä¸æç¨ï¼ (a) å®å ¨ä¸éæç对象 (è¿ç§æ åµä¸è¦ä¸»å¨ä½¿ç¨ typedef æ¥ **éè** è¿ä¸ªå¯¹è±¡å®é ä¸ æ¯ä»ä¹)ã ä¾å¦ï¼ ``pte_t`` çä¸éæ对象ï¼ä½ åªè½ç¨åéç访é®å½æ°æ¥è®¿é®å®ä»¬ã .. note:: ä¸éææ§å "访é®å½æ°" æ¬èº«æ¯ä¸å¥½çãæä»¬ä½¿ç¨ pte_t çç±»åçåå å¨äºç çæ¯å®å ¨æ²¡æä»»ä½å ±ç¨çå¯è®¿é®ä¿¡æ¯ã (b) æ¸ æ¥çæ´æ°ç±»åï¼å¦æ¤ï¼è¿å±æ½è±¡å°±å¯ä»¥ **帮å©** æ¶é¤å°åºæ¯ ``int`` è¿æ¯ ``long`` çæ··æ·ã u8/u16/u32 æ¯å®å ¨æ²¡æé®é¢ç typedefï¼ä¸è¿å®ä»¬æ´ç¬¦åç±»å« (d) èä¸æ¯è¿éã .. note:: è¦è¿æ ·åï¼å¿ é¡»äºåºæå ãå¦ææ个åéæ¯ ``unsigned long`` ï¼é£ä¹æ²¡æå¿ è¦ typedef unsigned long myflags_t; ä¸è¿å¦ææä¸ä¸ªæç¡®çåå ï¼æ¯å¦å®å¨æç§æ åµä¸å¯è½ä¼æ¯ä¸ä¸ª ``unsigned int`` èå¨å ¶ä»æ åµä¸å¯è½ä¸º ``unsigned long`` ï¼é£ä¹å°±ä¸è¦ç¹è±«ï¼è¯·å¡å¿ ä½¿ç¨ typedefã (c) å½ä½ ä½¿ç¨ sparse æåé¢çå建ä¸ä¸ª **æ°** ç±»åæ¥åç±»åæ£æ¥çæ¶åã (d) åæ å C99 ç±»åç¸åçç±»åï¼å¨æäºä¾å¤çæ åµä¸ã è½ç¶è®©ç¼çåèçæ¥éåºæ°çæ åç±»åæ¯å¦ ``uint32_t`` ä¸éè¦è±å¾å¤æ¶é´ï¼å¯ æ¯æäºäººä»ç¶æç»ä½¿ç¨å®ä»¬ã å æ¤ï¼Linux ç¹æççåäºæ åç±»åç ``u8/u16/u32/u64`` ç±»ååå®ä»¬çæç¬¦å· ç±»åæ¯è¢«å 许çââ尽管å¨ä½ èªå·±çæ°ä»£ç ä¸ï¼å®ä»¬ä¸æ¯å¼ºå¶è¦æ±è¦ä½¿ç¨çã å½ç¼è¾å·²ç»ä½¿ç¨äºæ个类åéçå·²æ代ç æ¶ï¼ä½ åºè¯¥éµå¾ªé£äºä»£ç ä¸å·²ç»ååºçé æ©ã (e) å¯ä»¥å¨ç¨æ·ç©ºé´å®å ¨ä½¿ç¨çç±»åã å¨æäºç¨æ·ç©ºé´å¯è§çç»æä½éï¼æ们ä¸è½è¦æ± C99 ç±»åèä¸ä¸è½ç¨ä¸é¢æå°ç ``u32`` ç±»åãå æ¤ï¼æ们å¨ä¸ç¨æ·ç©ºé´å ±äº«çææç»æä½ä¸ä½¿ç¨ __u32 å类似 çç±»åã å¯è½è¿æå ¶ä»çæ åµï¼ä¸è¿åºæ¬çè§åæ¯ **æ°¸è¿ä¸è¦** ä½¿ç¨ typedefï¼é¤éä½ å¯ä»¥æ ç¡®çåºç¨ä¸è¿°æ个è§åä¸çä¸ä¸ªã æ»çæ¥è¯´ï¼å¦æä¸ä¸ªæéæè ä¸ä¸ªç»æä½éçå ç´ å¯ä»¥åçç被ç´æ¥è®¿é®å°ï¼é£ä¹å®ä»¬ å°±ä¸åºè¯¥æ¯ä¸ä¸ª typedefã 6) å½æ° ------------------------------ å½æ°åºè¯¥ç®çèæ¼äº®ï¼å¹¶ä¸åªå®æä¸ä»¶äºæ ãå½æ°åºè¯¥å¯ä»¥ä¸å±æè 两å±æ¾ç¤ºå® (æ们 é½ç¥é ISO/ANSI å±å¹å¤§å°æ¯ 80x24)ï¼åªåä¸ä»¶äºæ ï¼èä¸æå®å好ã ä¸ä¸ªå½æ°çæ大é¿åº¦æ¯å该å½æ°çå¤æ度å缩è¿çº§æ°æåæ¯çãæ以ï¼å¦æä½ æä¸ä¸ªç 论ä¸å¾ç®åçåªæä¸ä¸ªå¾é¿ (ä½æ¯ç®å) ç case è¯å¥çå½æ°ï¼èä¸ä½ éè¦å¨æ¯ä¸ª case éåå¾å¤å¾å°çäºæ ï¼è¿æ ·çå½æ°å°½ç®¡å¾é¿ï¼ä½ä¹æ¯å¯ä»¥çã ä¸è¿ï¼å¦æä½ æä¸ä¸ªå¤æçå½æ°ï¼èä¸ä½ æçä¸ä¸ªå¤©åä¸æ¯å¾é«çé«ä¸ä¸å¹´çº§å¦çå¯è½ çè³æä¸æ¸ æ¥è¿ä¸ªå½æ°çç®çï¼ä½ åºè¯¥ä¸¥æ ¼éµå®åé¢æå°çé¿åº¦éå¶ã使ç¨è¾ å©å½æ°ï¼ 并为ä¹åä¸ªå ·æè¿°æ§çåå (å¦æä½ è§å¾å®ä»¬çæ§è½å¾éè¦çè¯ï¼å¯ä»¥è®©ç¼è¯å¨å èå® ä»¬ï¼è¿æ ·çææå¾å¾ä¼æ¯ä½ åä¸ä¸ªå¤æå½æ°çææè¦å¥½ã) å½æ°çå¦å¤ä¸ä¸ªè¡¡éæ åæ¯æ¬å°åéçæ°éãæ¤æ°éä¸åºè¶ è¿ 5ï¼10 个ï¼å¦åä½ çå½æ° å°±æé®é¢äºãéæ°èèä¸ä¸ä½ çå½æ°ï¼æå®åæææ´å°çå½æ°ã人ç大èä¸è¬å¯ä»¥è½»æ¾ çåæ¶è·è¸ª 7 个ä¸åçäºç©ï¼å¦æåå¢å¤çè¯ï¼å°±ä¼ç³æ¶äºãå³ä¾¿ä½ èªé¢è¿äººï¼ä½ ä¹å¯ è½ä¼è®°ä¸æ¸ ä½ 2 个ææååè¿çäºæ ã å¨æºæ件éï¼ä½¿ç¨ç©ºè¡éå¼ä¸åçå½æ°ãå¦æ该å½æ°éè¦è¢«å¯¼åºï¼å®ç **EXPORT** å® åºè¯¥ç´§è´´å¨å®çç»æ大æ¬å·ä¹ä¸ãæ¯å¦ï¼ .. code-block:: c int system_is_up(void) { return system_state == SYSTEM_RUNNING; } EXPORT_SYMBOL(system_is_up); å¨å½æ°ååä¸ï¼å å«å½æ°ååå®ä»¬çæ°æ®ç±»åãè½ç¶ C è¯è¨é没æè¿æ ·çè¦æ±ï¼å¨ Linux éè¿æ¯æå¡çåæ³ï¼å 为è¿æ ·å¯ä»¥å¾ç®åçç»è¯»è æä¾æ´å¤çæä»·å¼çä¿¡æ¯ã 7) éä¸çå½æ°éåºéå¾ ------------------------------ è½ç¶è¢«æäºäººå£°ç§°å·²ç»è¿æ¶ï¼ä½æ¯ goto è¯å¥ççä»·ç©è¿æ¯ç»å¸¸è¢«ç¼è¯å¨æ使ç¨ï¼å ·ä½ å½¢å¼æ¯æ æ¡ä»¶è·³è½¬æ令ã å½ä¸ä¸ªå½æ°ä»å¤ä¸ªä½ç½®éåºï¼å¹¶ä¸éè¦åä¸äºç±»ä¼¼æ¸ çç常è§æä½æ¶ï¼goto è¯å¥å°±å¾æ¹ 便äºãå¦æ并ä¸éè¦æ¸ çæä½ï¼é£ä¹ç´æ¥ return å³å¯ã éæ©ä¸ä¸ªè½å¤è¯´æ goto è¡ä¸ºæå®ä¸ºä½åå¨çæ ç¾åãå¦æ goto è¦éæ¾ ``buffer``, ä¸ä¸ªä¸éçååå¯ä»¥æ¯ ``out_free_buffer:`` ãå«å»ä½¿ç¨å ``err1:`` å ``err2:`` è¿æ ·çGW_BASIC å称ï¼å 为ä¸æ¦ä½ æ·»å æå é¤äº (å½æ°ç) éåºè·¯å¾ï¼ä½ å°±å¿ é¡»å¯¹å®ä»¬ éæ°ç¼å·ï¼è¿æ ·ä¼é¾ä»¥å»æ£éªæ£ç¡®æ§ã ä½¿ç¨ goto ççç±æ¯ï¼ - æ æ¡ä»¶è¯å¥å®¹æç解åè·è¸ª - åµå¥ç¨åº¦åå° - å¯ä»¥é¿å ç±äºä¿®æ¹æ¶å¿è®°æ´æ°ä¸ªå«çéåºç¹è导è´é误 - 让ç¼è¯å¨çå»å é¤åä½ä»£ç çå·¥ä½ ;) .. code-block:: c int fun(int a) { int result = 0; char *buffer; buffer = kmalloc(SIZE, GFP_KERNEL); if (!buffer) return -ENOMEM; if (condition1) { while (loop1) { ... } result = 1; goto out_free_buffer; } ... out_free_buffer: kfree(buffer); return result; } ä¸ä¸ªéè¦æ³¨æç常è§éè¯¯æ¯ ``ä¸ä¸ª err é误`` ï¼å°±åè¿æ ·ï¼ .. code-block:: c err: kfree(foo->bar); kfree(foo); return ret; è¿æ®µä»£ç çé误æ¯ï¼å¨æäºéåºè·¯å¾ä¸ ``foo`` æ¯ NULLãé常æ åµä¸ï¼éè¿æå®å离 æ两个é误æ ç¾ ``err_free_bar:`` å ``err_free_foo:`` æ¥ä¿®å¤è¿ä¸ªéè¯¯ï¼ .. code-block:: c err_free_bar: kfree(foo->bar); err_free_foo: kfree(foo); return ret; çæ³æ åµä¸ï¼ä½ åºè¯¥æ¨¡æé误æ¥æµè¯ææéåºè·¯å¾ã 8) 注é ------------------------------ 注éæ¯å¥½çï¼ä¸è¿æè¿åº¦æ³¨éçå±é©ãæ°¸è¿ä¸è¦å¨æ³¨éé解éä½ ç代ç æ¯å¦ä½è¿ä½çï¼ æ´å¥½çåæ³æ¯è®©å«äººä¸çä½ ç代ç å°±å¯ä»¥æç½ï¼è§£éåçå¾å·®ç代ç æ¯æµªè´¹æ¶é´ã ä¸è¬çï¼ä½ æ³è¦ä½ ç注éåè¯å«äººä½ ç代ç åäºä»ä¹ï¼èä¸æ¯æä¹åçãä¹è¯·ä½ ä¸è¦æ 注éæ¾å¨ä¸ä¸ªå½æ°ä½å é¨ï¼å¦æå½æ°å¤æå°ä½ éè¦ç¬ç«ç注éå ¶ä¸çä¸é¨åï¼ä½ å¾å¯è½ éè¦åå°ç¬¬å ç« çä¸çãä½ å¯ä»¥åä¸äºå°æ³¨éæ¥æ³¨ææè¦åæäºå¾èªæ (æè 槽ç³) ç åæ³ï¼ä½ä¸è¦å 太å¤ãä½ åºè¯¥åçï¼æ¯æ注éæ¾å¨å½æ°ç头é¨ï¼åè¯äººä»¬å®åäºä»ä¹ï¼ ä¹å¯ä»¥å ä¸å®åè¿äºäºæ çåå ã å½æ³¨éå æ ¸ API å½æ°æ¶ï¼è¯·ä½¿ç¨ kernel-doc æ ¼å¼ã请ç Documentation/doc-guide/ å scripts/kernel-doc 以è·å¾è¯¦ç»ä¿¡æ¯ã é¿ (å¤è¡) 注éçé¦éé£æ ¼æ¯ï¼ .. code-block:: c /* * This is the preferred style for multi-line * comments in the Linux kernel source code. * Please use it consistently. * * Description: A column of asterisks on the left side, * with beginning and ending almost-blank lines. */ 对äºå¨ net/ å drivers/net/ çæ件ï¼é¦éçé¿ (å¤è¡) 注éé£æ ¼æäºä¸åã .. code-block:: c /* The preferred comment style for files in net/ and drivers/net * looks like this. * * It is nearly the same as the generally preferred comment style, * but there is no initial almost-blank line. */ 注éæ°æ®ä¹æ¯å¾éè¦çï¼ä¸ç®¡æ¯åºæ¬ç±»åè¿æ¯è¡çç±»åã为äºæ¹ä¾¿å®ç°è¿ä¸ç¹ï¼æ¯ä¸è¡ åºåªå£°æä¸ä¸ªæ°æ® (ä¸è¦ä½¿ç¨éå·æ¥ä¸æ¬¡å£°æå¤ä¸ªæ°æ®)ãè¿æ ·ä½ å°±æ空é´æ¥ä¸ºæ¯ä¸ªæ°æ® åä¸æ®µå°æ³¨éæ¥è§£éå®ä»¬çç¨éäºã 9) ä½ å·²ç»æäºæ å¼ç³äº ------------------------------ è¿æ²¡ä»ä¹ï¼æ们é½æ¯è¿æ ·ãå¯è½ä½ ç使ç¨äºå¾é¿æ¶é´ Unix çæåå·²ç»åè¯ä½ ``GNU emacs`` è½èªå¨å¸®ä½ æ ¼å¼å C æºä»£ç ï¼èä¸ä½ ä¹æ³¨æå°äºï¼ç¡®å®æ¯è¿æ ·ï¼ä¸è¿å® æ使ç¨çé»è®¤å¼åæ们æ³è¦çç¸å»çè¿ (å®é ä¸ï¼çè³æ¯éæºæçè¿è¦å·®ââæ æ°ä¸ªç´å å¨ GNU emacs éæåæ°¸è¿ä¸ä¼åé åºä¸ä¸ªå¥½ç¨åº) (è¯æ³¨ï¼Infinite Monkey Theorem) æä»¥ä½ è¦ä¹æ¾å¼ GNU emacsï¼è¦ä¹æ¹åå®è®©å®ä½¿ç¨æ´åçç设å®ãè¦éç¨åä¸ä¸ªæ¹æ¡ï¼ ä½ å¯ä»¥æä¸é¢è¿æ®µç²è´´å°ä½ ç .emacs æ件éã .. code-block:: none (defun c-lineup-arglist-tabs-only (ignored) "Line up argument lists by tabs, not spaces" (let* ((anchor (c-langelem-pos c-syntactic-element)) (column (c-langelem-2nd-pos c-syntactic-element)) (offset (- (1+ column) anchor)) (steps (floor offset c-basic-offset))) (* (max steps 1) c-basic-offset))) (dir-locals-set-class-variables 'linux-kernel '((c-mode . ( (c-basic-offset . 8) (c-label-minimum-indentation . 0) (c-offsets-alist . ( (arglist-close . c-lineup-arglist-tabs-only) (arglist-cont-nonempty . (c-lineup-gcc-asm-reg c-lineup-arglist-tabs-only)) (arglist-intro . +) (brace-list-intro . +) (c . c-lineup-C-comments) (case-label . 0) (comment-intro . c-lineup-comment) (cpp-define-intro . +) (cpp-macro . -1000) (cpp-macro-cont . +) (defun-block-intro . +) (else-clause . 0) (func-decl-cont . +) (inclass . +) (inher-cont . c-lineup-multi-inher) (knr-argdecl-intro . 0) (label . -1000) (statement . 0) (statement-block-intro . +) (statement-case-intro . +) (statement-cont . +) (substatement . +) )) (indent-tabs-mode . t) (show-trailing-whitespace . t) )))) (dir-locals-set-directory-class (expand-file-name "~/src/linux-trees") 'linux-kernel) è¿ä¼è®© emacs å¨ ``~/src/linux-trees`` ä¸ç C æºæ件è·å¾æ´å¥½çå æ ¸ä»£ç é£æ ¼ã ä¸è¿å°±ç®ä½ å°è¯è®© emacs æ£ç¡®çæ ¼å¼å代ç 失败äºï¼ä¹å¹¶ä¸æå³çä½ å¤±å»äºä¸åï¼è¿å¯ ä»¥ç¨ ``indent`` ã ä¸è¿ï¼GNU indent ä¹æå GNU emacs ä¸æ ·æé®é¢ç设å®ï¼æä»¥ä½ éè¦ç»å®ä¸äºå½ä»¤é 项ãä¸è¿ï¼è¿è¿ä¸ç®å¤ªç³ç³ï¼å 为就ç®æ¯ GNU indent çä½è ä¹è®¤å K&R çæå¨æ§ (GNU ç人并ä¸æ¯å人ï¼ä»ä»¬åªæ¯å¨è¿ä¸ªé®é¢ä¸è¢«ä¸¥éç误导äº)ï¼æä»¥ä½ åªè¦ç» indent æå®é项 ``-kr -i8`` (代表 ``K&Rï¼8 å符缩è¿``)ï¼æä½¿ç¨ ``scripts/Lindent`` è¿æ ·å°±å¯ä»¥ä»¥ææ¶é«¦çæ¹å¼ç¼©è¿æºä»£ç ã ``indent`` æå¾å¤é项ï¼ç¹å«æ¯éæ°æ ¼å¼å注éçæ¶åï¼ä½ å¯è½éè¦çä¸ä¸å®çæåã ä¸è¿è®°ä½ï¼ ``indent`` ä¸è½ä¿®æ£åçç¼ç¨ä¹ æ¯ã 10) Kconfig é ç½®æ件 ------------------------------ 对äºéå¸æºç æ çææ Kconfig* é ç½®æ件æ¥è¯´ï¼å®ä»¬ç¼©è¿æ¹å¼ææä¸åãç´§æ¨ç ``config`` å®ä¹çè¡ï¼ç¨ä¸ä¸ªå¶è¡¨ç¬¦ç¼©è¿ï¼ç¶è help ä¿¡æ¯ç缩è¿åé¢å¤å¢å 2 个空 æ ¼ã举个ä¾å:: config AUDIT bool "Auditing support" depends on NET help Enable auditing infrastructure that can be used with another kernel subsystem, such as SELinux (which requires this for logging of avc messages output). Does not do system-call auditing without CONFIG_AUDITSYSCALL. èé£äºå±é©çåè½ (æ¯å¦æäºæ件系ç»çåæ¯æ) åºè¯¥å¨å®ä»¬çæ示å符串éæ¾èç声 æè¿ä¸ç¹:: config ADFS_FS_RW bool "ADFS write support (DANGEROUS)" depends on ADFS_FS ... è¦æ¥çé ç½®æ件çå®æ´ææ¡£ï¼è¯·ç Documentation/kbuild/kconfig-language.rstã 11) æ°æ®ç»æ ------------------------------ å¦æä¸ä¸ªæ°æ®ç»æï¼å¨å建åéæ¯å®çå线æ§è¡ç¯å¢ä¹å¤å¯è§ï¼é£ä¹å®å¿ é¡»è¦æä¸ä¸ªå¼ ç¨è®¡æ°å¨ãå æ ¸é没æåå¾æ¶é (并ä¸å æ ¸ä¹å¤çåå¾æ¶éæ ¢ä¸æçä½ä¸)ï¼è¿æå³çä½ ç»å¯¹éè¦è®°å½ä½ 对è¿ç§æ°æ®ç»æç使ç¨æ åµã å¼ç¨è®¡æ°æå³çä½ è½å¤é¿å ä¸éï¼å¹¶ä¸å 许å¤ä¸ªç¨æ·å¹¶è¡è®¿é®è¿ä¸ªæ°æ®ç»æââèä¸éè¦ æ å¿è¿ä¸ªæ°æ®ç»æä» ä» å 为ææ¶ä¸è¢«ä½¿ç¨å°±æ¶å¤±äºï¼é£äºç¨æ·å¯è½ä¸è¿æ¯æ²ç¡äºä¸éµæ è åäºä¸äºå ¶ä»äºæ èå·²ã 注æä¸é **ä¸è½** å代å¼ç¨è®¡æ°ãä¸éæ¯ä¸ºäºä¿ææ°æ®ç»æçä¸è´æ§ï¼èå¼ç¨è®¡æ°æ¯ä¸ 个å å管çæå·§ãé常äºè é½éè¦ï¼ä¸è¦æ两个ææ··äºã å¾å¤æ°æ®ç»æå®é ä¸æ 2 级å¼ç¨è®¡æ°ï¼å®ä»¬é常æä¸å ``ç±»`` çç¨æ·ãå类计æ°å¨ç» 计åç±»ç¨æ·çæ°éï¼æ¯å½å类计æ°å¨åè³é¶æ¶ï¼å ¨å±è®¡æ°å¨åä¸ã è¿ç§ ``å¤çº§å¼ç¨è®¡æ°`` çä¾åå¯ä»¥å¨å å管ç (``struct mm_struct``: mm_users å mm_count)ï¼åæä»¶ç³»ç» (``struct super_block``: s_count å s_active) ä¸æ¾å°ã è®°ä½ï¼å¦æå¦ä¸ä¸ªæ§è¡çº¿ç´¢å¯ä»¥æ¾å°ä½ çæ°æ®ç»æï¼ä½è¿ä¸ªæ°æ®ç»æ没æå¼ç¨è®¡æ°å¨ï¼ è¿éå ä¹è¯å®æ¯ä¸ä¸ª bugã 12) å®ï¼æ举åRTL ------------------------------ ç¨äºå®ä¹å¸¸éçå®çåååæ举éçæ ç¾éè¦å¤§åã .. code-block:: c #define CONSTANT 0x12345 å¨å®ä¹å 个ç¸å ³ç常éæ¶ï¼æ好ç¨æ举ã å®çåå请ç¨å¤§ååæ¯ï¼ä¸è¿å½¢å¦å½æ°çå®çååå¯ä»¥ç¨å°ååæ¯ã ä¸è¬çï¼å¦æè½åæå èå½æ°å°±ä¸è¦åæåå½æ°çå®ã å«æå¤ä¸ªè¯å¥çå®åºè¯¥è¢«å å«å¨ä¸ä¸ª do-while 代ç åéï¼ .. code-block:: c #define macrofun(a, b, c) \ do { \ if (a == 5) \ do_this(b, c); \ } while (0) 使ç¨å®çæ¶ååºé¿å çäºæ ï¼ 1) å½±åæ§å¶æµç¨çå®ï¼ .. code-block:: c #define FOO(x) \ do { \ if (blah(x) < 0) \ return -EBUGGERED; \ } while (0) **é常** ä¸å¥½ãå®çèµ·æ¥åä¸ä¸ªå½æ°ï¼ä¸è¿å´è½å¯¼è´ ``è°ç¨`` å®çå½æ°éåºï¼ä¸è¦æ 乱读è 大èéçè¯æ³åæå¨ã 2) ä¾èµäºä¸ä¸ªåºå®ååçæ¬å°åéçå®ï¼ .. code-block:: c #define FOO(val) bar(index, val) å¯è½çèµ·æ¥åæ¯ä¸ªä¸éçä¸è¥¿ï¼ä¸è¿å®é常容ææ读代ç ç人æç³æ¶ï¼èä¸å®¹æ导è´çèµ· æ¥ä¸ç¸å ³çæ¹å¨å¸¦æ¥é误ã 3) ä½ä¸ºå·¦å¼ç带åæ°çå®ï¼ FOO(x) = yï¼å¦ææ人æ FOO åæä¸ä¸ªå èå½æ°çè¯ï¼è¿ ç§ç¨æ³å°±ä¼åºéäºã 4) å¿è®°äºä¼å 级ï¼ä½¿ç¨è¡¨è¾¾å¼å®ä¹å¸¸éçå®å¿ é¡»å°è¡¨è¾¾å¼ç½®äºä¸å¯¹å°æ¬å·ä¹å ã带åæ° çå®ä¹è¦æ³¨ææ¤ç±»é®é¢ã .. code-block:: c #define CONSTANT 0x4000 #define CONSTEXP (CONSTANT | 3) 5) å¨å®éå®ä¹ç±»ä¼¼å½æ°çæ¬å°åéæ¶å½åå²çªï¼ .. code-block:: c #define FOO(x) \ ({ \ typeof(x) ret; \ ret = calc_ret(x); \ (ret); \ }) ret æ¯æ¬å°åéçéç¨åå - __foo_ret æ´ä¸å®¹æä¸ä¸ä¸ªå·²åå¨çåéå²çªã cpp æå对å®ç讲解å¾è¯¦ç»ãgcc internals æåä¹è¯¦ç»è®²è§£äº RTLï¼å æ ¸éçæ±ç¼è¯ è¨ç»å¸¸ç¨å°å®ã 13) æå°å æ ¸æ¶æ¯ ------------------------------ å æ ¸å¼åè åºè¯¥æ¯åè¿è¯å¥½æè²çã请ä¸å®æ³¨æå æ ¸ä¿¡æ¯çæ¼åï¼ä»¥ç»äººä»¥å¥½çå°è±¡ã ä¸è¦ç¨ä¸è§èçåè¯æ¯å¦ ``dont``ï¼èè¦ç¨ ``do not`` æè ``don't`` ãä¿è¯è¿äºä¿¡ æ¯ç®åæäº,æ æ§ä¹ã å æ ¸ä¿¡æ¯ä¸å¿ 以è±æå¥å·ç»æã å¨å°æ¬å·éæå°æ°å (%d) 没æä»»ä½ä»·å¼ï¼åºè¯¥é¿å è¿æ ·åã <linux/device.h> éæä¸äºé©±å¨æ¨¡åè¯æå®ï¼ä½ åºè¯¥ä½¿ç¨å®ä»¬ï¼ä»¥ç¡®ä¿ä¿¡æ¯å¯¹åºäºæ£ç¡® ç设å¤å驱å¨ï¼å¹¶ä¸è¢«æ è®°äºæ£ç¡®çæ¶æ¯çº§å«ãè¿äºå®æï¼dev_err(), dev_warn(), dev_info() ççã对äºé£äºä¸åæ个ç¹å®è®¾å¤ç¸å ³è¿çä¿¡æ¯ï¼<linux/printk.h> å®ä¹ äº pr_notice(), pr_info(), pr_warn(), pr_err() åå ¶ä»ã ååºå¥½çè°è¯ä¿¡æ¯å¯ä»¥æ¯ä¸ä¸ªå¾å¤§çææï¼ä¸æ¦ä½ ååºåï¼è¿äºä¿¡æ¯å¨è¿ç¨é¤éæ¶è½æ ä¾æ大ç帮å©ãç¶èæå°è°è¯ä¿¡æ¯çå¤çæ¹å¼åæå°éè°è¯ä¿¡æ¯ä¸åãå ¶ä» pr_XXX() å½æ°è½æ æ¡ä»¶å°æå°ï¼pr_debug() å´ä¸ï¼é»è®¤æ åµä¸å®ä¸ä¼è¢«ç¼è¯ï¼é¤éå®ä¹äº DEBUG æ设å®äº CONFIG_DYNAMIC_DEBUGãå®é è¿åæ ·æ¯ä¸ºäº dev_dbg()ï¼ä¸ä¸ªç¸å ³çº¦å®æ¯å¨ä¸ 个已ç»å¼å¯äº DEBUG æ¶ï¼ä½¿ç¨ VERBOSE_DEBUG æ¥æ·»å dev_vdbg()ã 许å¤åç³»ç»æ¥æ Kconfig è°è¯é项æ¥å¼å¯ -DDEBUG å¨å¯¹åºç Makefile éé¢ï¼å¨å ¶ä» æ åµä¸ï¼ç¹æ®æä»¶ä½¿ç¨ #define DEBUGãå½ä¸æ¡è°è¯ä¿¡æ¯éè¦è¢«æ æ¡ä»¶æå°æ¶ï¼ä¾å¦ï¼ å¦æå·²ç»å å«ä¸ä¸ªè°è¯ç¸å ³ç #ifdef æ¡ä»¶ï¼printk(KERN_DEBUG ...) å°±å¯è¢«ä½¿ç¨ã 14) åé å å ------------------------------ å æ ¸æä¾äºä¸é¢çä¸è¬ç¨éçå ååé å½æ°ï¼ kmalloc(), kzalloc(), kmalloc_array(), kcalloc(), vmalloc() å vzalloc()ã 请åè API æ档以è·åæå ³å®ä»¬ç详ç»ä¿¡æ¯ã ä¼ éç»æä½å¤§å°çé¦éå½¢å¼æ¯è¿æ ·çï¼ .. code-block:: c p = kmalloc(sizeof(*p), ...); å¦å¤ä¸ç§ä¼ éæ¹å¼ä¸ï¼sizeof çæä½æ°æ¯ç»æä½çååï¼è¿æ ·ä¼éä½å¯è¯»æ§ï¼å¹¶ä¸å¯è½ ä¼å¼å ¥ bugãæå¯è½æéåéç±»å被æ¹åæ¶ï¼è对åºçä¼ éç»å ååé å½æ°ç sizeof çç»æä¸åã 强å¶è½¬æ¢ä¸ä¸ª void æéè¿åå¼æ¯å¤ä½çãC è¯è¨æ¬èº«ä¿è¯äºä» void æéå°å ¶ä»ä»»ä½ æéç±»åç转æ¢æ¯æ²¡æé®é¢çã åé ä¸ä¸ªæ°ç»çé¦éå½¢å¼æ¯è¿æ ·çï¼ .. code-block:: c p = kmalloc_array(n, sizeof(...), ...); åé ä¸ä¸ªé¶é¿æ°ç»çé¦éå½¢å¼æ¯è¿æ ·çï¼ .. code-block:: c p = kcalloc(n, sizeof(...), ...); 两ç§å½¢å¼æ£æ¥åé å¤§å° n * sizeof(...) ç溢åºï¼å¦æ溢åºè¿å NULLã 15) å èå¼ç ------------------------------ æä¸ä¸ªå¸¸è§çè¯¯è§£æ¯ ``å è`` æ¯ gcc æä¾çå¯ä»¥è®©ä»£ç è¿è¡æ´å¿«çä¸ä¸ªé项ãè½ç¶ä½¿ ç¨å èå½æ°ææ¶åæ¯æ°å½ç (æ¯å¦ä½ä¸ºä¸ç§æ¿ä»£å®çæ¹å¼ï¼è¯·ç第åäºç« )ï¼ä¸è¿å¾å¤æ åµä¸ä¸æ¯è¿æ ·ãinline çè¿åº¦ä½¿ç¨ä¼ä½¿å æ ¸å大ï¼ä»è使æ´ä¸ªç³»ç»è¿è¡é度åæ ¢ã å 为ä½ç§¯å¤§å æ ¸ä¼å ç¨æ´å¤çæ令é«éç¼åï¼èä¸ä¼å¯¼è´ pagecache çå¯ç¨å ååå°ã æ³è±¡ä¸ä¸ï¼ä¸æ¬¡ pagecache æªå½ä¸å°±ä¼å¯¼è´ä¸æ¬¡ç£ç寻åï¼å°èæ¶ 5 毫ç§ã5 毫ç§ç æ¶é´å CPU è½æ§è¡å¾å¤å¾å¤æ令ã ä¸ä¸ªåºæ¬çååæ¯å¦æä¸ä¸ªå½æ°æ 3 è¡ä»¥ä¸ï¼å°±ä¸è¦æå®åæå èå½æ°ãè¿ä¸ªååçä¸ ä¸ªä¾å¤æ¯ï¼å¦æä½ ç¥éæ个åæ°æ¯ä¸ä¸ªç¼è¯æ¶å¸¸éï¼èä¸å 为è¿ä¸ªå¸¸éä½ ç¡®å®ç¼è¯å¨å¨ ç¼è¯æ¶è½ä¼åæä½ çå½æ°ç大é¨å代ç ï¼é£ä»ç¶å¯ä»¥ç»å®å ä¸ inline å ³é®åã kmalloc() å èå½æ°å°±æ¯ä¸ä¸ªå¾å¥½çä¾åã 人们ç»å¸¸ä¸»å¼ ç» static çèä¸åªç¨äºä¸æ¬¡çå½æ°å ä¸ inlineï¼å¦æ¤ä¸ä¼æä»»ä½æå¤±ï¼ å 为没æä»ä¹å¥½æè¡¡çãè½ç¶ä»ææ¯ä¸è¯´è¿æ¯æ£ç¡®çï¼ä½æ¯å®é ä¸è¿ç§æ åµä¸å³ä½¿ä¸å inline gcc ä¹å¯ä»¥èªå¨ä½¿å ¶å èãèä¸å ¶ä»ç¨æ·å¯è½ä¼è¦æ±ç§»é¤ inlineï¼ç±æ¤èæ¥ç äºè®ºä¼æµæ¶ inline èªèº«çæ½å¨ä»·å¼ï¼å¾ä¸å¿å¤±ã 16) å½æ°è¿åå¼åå½å ------------------------------ å½æ°å¯ä»¥è¿åå¤ç§ä¸åç±»åçå¼ï¼æ常è§çä¸ç§æ¯è¡¨æå½æ°æ§è¡æåæè 失败çå¼ãè¿æ · çä¸ä¸ªå¼å¯ä»¥è¡¨ç¤ºä¸ºä¸ä¸ªé误代ç æ´æ° (-Exxxï¼å¤±è´¥ï¼0ï¼æå) æè ä¸ä¸ª ``æå`` å¸å°å¼ (0ï¼å¤±è´¥ï¼é0ï¼æå)ã æ··å使ç¨è¿ä¸¤ç§è¡¨è¾¾æ¹å¼æ¯é¾äºåç°ç bug çæ¥æºãå¦æ C è¯è¨æ¬èº«ä¸¥æ ¼åºåæ´å½¢å å¸å°ååéï¼é£ä¹ç¼è¯å¨å°±è½å¤å¸®æ们åç°è¿äºé误... ä¸è¿ C è¯è¨ä¸åºåã为äºé¿å 产çè¿ç§ bugï¼è¯·éµå¾ªä¸é¢çæ¯ä¾:: å¦æå½æ°çååæ¯ä¸ä¸ªå¨ä½æè 强å¶æ§çå½ä»¤ï¼é£ä¹è¿ä¸ªå½æ°åºè¯¥è¿åé误代 ç æ´æ°ãå¦ææ¯ä¸ä¸ªå¤æï¼é£ä¹å½æ°åºè¯¥è¿åä¸ä¸ª "æå" å¸å°å¼ã æ¯å¦ï¼ ``add work`` æ¯ä¸ä¸ªå½ä»¤ï¼æ以 add_work() å¨æåæ¶è¿å 0ï¼å¨å¤±è´¥æ¶è¿å -EBUSYã类似çï¼å 为 ``PCI device present`` æ¯ä¸ä¸ªå¤æï¼æ以 pci_dev_present() å¨æåæ¾å°ä¸ä¸ªå¹é ç设å¤æ¶åºè¯¥è¿å 1ï¼å¦ææ¾ä¸å°æ¶åºè¯¥è¿å 0ã ææ EXPORTed å½æ°é½å¿ é¡»éµå®è¿ä¸ªæ¯ä¾ï¼ææçå ¬å ±å½æ°ä¹é½åºè¯¥å¦æ¤ãç§æ (static) å½æ°ä¸éè¦å¦æ¤ï¼ä½æ¯æ们ä¹æ¨èè¿æ ·åã è¿åå¼æ¯å®é 计ç®ç»æèä¸æ¯è®¡ç®æ¯å¦æåçæ å¿çå½æ°ä¸åæ¤æ¯ä¾çéå¶ãä¸è¬çï¼ ä»ä»¬éè¿è¿åä¸äºæ£å¸¸å¼èå´ä¹å¤çç»ææ¥è¡¨ç¤ºåºéãå ¸åçä¾åæ¯è¿åæéçå½æ°ï¼ ä»ä»¬ä½¿ç¨ NULL æè ERR_PTR æºå¶æ¥æ¥åé误ã 17) ä¸è¦éæ°åæå æ ¸å® ------------------------------ 头æ件 include/linux/kernel.h å å«äºä¸äºå®ï¼ä½ åºè¯¥ä½¿ç¨å®ä»¬ï¼èä¸è¦èªå·±åä¸äº å®ä»¬çåç§ãæ¯å¦ï¼å¦æä½ éè¦è®¡ç®ä¸ä¸ªæ°ç»çé¿åº¦ï¼ä½¿ç¨è¿ä¸ªå® .. code-block:: c #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 类似çï¼å¦æä½ è¦è®¡ç®æç»æä½æåç大å°ï¼ä½¿ç¨ .. code-block:: c #define sizeof_field(t, f) (sizeof(((t*)0)->f)) è¿æå¯ä»¥åä¸¥æ ¼çç±»åæ£æ¥ç min() å max() å®ï¼å¦æä½ éè¦å¯ä»¥ä½¿ç¨å®ä»¬ãä½ å¯ä»¥ èªå·±ççé£ä¸ªå¤´æ件éè¿å®ä¹äºä»ä¹ä½ å¯ä»¥æ¿æ¥ç¨çä¸è¥¿ï¼å¦ææå®ä¹çè¯ï¼ä½ å°±ä¸åº å¨ä½ ç代ç éèªå·±éæ°å®ä¹ã 18) ç¼è¾å¨æ¨¡å¼è¡åå ¶ä»éè¦ç½å¦çäºæ -------------------------------------------------- æä¸äºç¼è¾å¨å¯ä»¥è§£éåµå ¥å¨æºæ件éçç±ä¸äºç¹æ®æ è®°æ æçé 置信æ¯ãæ¯å¦ï¼emacs è½å¤è§£é被æ è®°æè¿æ ·çè¡ï¼ .. code-block:: c -*- mode: c -*- æè è¿æ ·çï¼ .. code-block:: c /* Local Variables: compile-command: "gcc -DMAGIC_DEBUG_FLAG foo.c" End: */ Vim è½å¤è§£éè¿æ ·çæ è®°ï¼ .. code-block:: c /* vim:set sw=8 noet */ ä¸è¦å¨æºä»£ç ä¸å å«ä»»ä½è¿æ ·çå 容ãæ¯ä¸ªäººé½æä»èªå·±çç¼è¾å¨é ç½®ï¼ä½ çæºæä»¶ä¸ åºè¯¥è¦çå«äººçé ç½®ãè¿å æ¬æå ³ç¼©è¿å模å¼é ç½®çæ è®°ã人们å¯ä»¥ä½¿ç¨ä»ä»¬èªå·±å®å¶ ç模å¼ï¼æè 使ç¨å ¶ä»å¯ä»¥äº§çæ£ç¡®ç缩è¿çå·§å¦æ¹æ³ã 19) å èæ±ç¼ ------------------------------ å¨ç¹å®æ¶æç代ç ä¸ï¼ä½ å¯è½éè¦å èæ±ç¼ä¸ CPU åå¹³å°ç¸å ³åè½è¿æ¥ãéè¦è¿ä¹åæ¶ å°±ä¸è¦ç¹è±«ãç¶èï¼å½ C å¯ä»¥å®æå·¥ä½æ¶ï¼ä¸è¦å¹³ç½æ æ å°ä½¿ç¨å èæ±ç¼ãå¨å¯è½çæ åµä¸ï¼ä½ å¯ä»¥å¹¶ä¸åºè¯¥ç¨ C å硬件æ²éã 请èèå»åæç»éç¨ä½å (wrap common bits) çå èæ±ç¼çç®åè¾ å©å½æ°ï¼å«å»éå¤ å°åä¸åªæç»å¾®å·®å¼å èæ±ç¼ãè®°ä½å èæ±ç¼å¯ä»¥ä½¿ç¨ C åæ°ã 大åï¼æä¸å®å¤æ度çæ±ç¼å½æ°åºè¯¥æ¾å¨ .S æ件å ï¼ç¨ç¸åºç C ååå®ä¹å¨ C 头æ 件ä¸ãæ±ç¼å½æ°ç C åååºè¯¥ä½¿ç¨ ``asmlinkage`` ã ä½ å¯è½éè¦ææ±ç¼è¯å¥æ 记为 volatileï¼ç¨æ¥é»æ¢ GCC å¨æ²¡åç°ä»»ä½å¯ä½ç¨åå°±æå® ç§»é¤äºãä½ ä¸å¿ æ»æ¯è¿æ ·åï¼å°½ç®¡ï¼è¿ä¸å¿ è¦ç举å¨ä¼éå¶ä¼åã å¨åä¸ä¸ªå å«å¤æ¡æ令çå个å èæ±ç¼è¯å¥æ¶ï¼ææ¯æ¡æ令ç¨å¼å·åå²èä¸åå ä¸è¡ï¼ é¤äºæåä¸æ¡æ令å¤ï¼å¨æ¯ä¸ªæ令ç»å°¾å ä¸ \n\tï¼è®©æ±ç¼è¾åºæ¶å¯ä»¥æ£ç¡®å°ç¼©è¿ä¸ä¸æ¡ æä»¤ï¼ .. code-block:: c asm ("magic %reg1, #42\n\t" "more_magic %reg2, %reg3" : /* outputs */ : /* inputs */ : /* clobbers */); 20) æ¡ä»¶ç¼è¯ ------------------------------ åªè¦å¯è½ï¼å°±ä¸è¦å¨ .c æ件éé¢ä½¿ç¨é¢å¤çæ¡ä»¶ (#if, #ifdef)ï¼è¿æ ·å让代ç æ´é¾ é 读并ä¸æ´é¾å»è·è¸ªé»è¾ãæ¿ä»£æ¹æ¡æ¯ï¼å¨å¤´æ件ä¸ç¨é¢å¤çæ¡ä»¶æä¾ç»é£äº .c æ件 使ç¨ï¼åç» #else æä¾ä¸ä¸ªç©ºæ¡© (no-op stub) çæ¬ï¼ç¶åå¨ .c æ件å æ æ¡ä»¶å°è°ç¨ é£äº (å®ä¹å¨å¤´æ件å ç) å½æ°ãè¿æ ·åï¼ç¼è¯å¨ä¼é¿å 为桩å½æ° (stub) çè°ç¨çæ ä»»ä½ä»£ç ï¼äº§ççç»ææ¯ç¸åçï¼ä½é»è¾å°æ´å æ¸ æ°ã æ好å¾åäºç¼è¯æ´ä¸ªå½æ°ï¼èä¸æ¯å½æ°çä¸é¨åæ表达å¼çä¸é¨åãä¸å ¶æ¾ä¸ä¸ª ifdef å¨è¡¨è¾¾å¼å ï¼ä¸å¦å解åºé¨åæå ¨é¨è¡¨è¾¾å¼ï¼æ¾è¿ä¸ä¸ªåç¬çè¾ å©å½æ°ï¼å¹¶åºç¨é¢å¤ç æ¡ä»¶å°è¿ä¸ªè¾ å©å½æ°å ã å¦æä½ æä¸ä¸ªå¨ç¹å®é ç½®ä¸ï¼å¯è½åææªä½¿ç¨çå½æ°æåéï¼ç¼è¯å¨ä¼è¦åå®å®ä¹äºä½ æªä½¿ç¨ï¼æå®æ 记为 __maybe_unused èä¸æ¯å°å®å å«å¨ä¸ä¸ªé¢å¤çæ¡ä»¶ä¸ã(ç¶èï¼å¦ æä¸ä¸ªå½æ°æåéæ»æ¯æªä½¿ç¨ï¼å°±ç´æ¥å é¤å®ã) å¨ä»£ç ä¸ï¼å°½å¯è½å°ä½¿ç¨ IS_ENABLED å®æ¥è½¬åæ个 Kconfig æ 记为 C çå¸å° 表达å¼ï¼å¹¶å¨ä¸è¬ç C æ¡ä»¶ä¸ä½¿ç¨å®ï¼ .. code-block:: c if (IS_ENABLED(CONFIG_SOMETHING)) { ... } ç¼è¯å¨ä¼å常éæå ï¼ç¶åå°±åä½¿ç¨ #ifdef é£æ ·å»å å«ææé¤ä»£ç åï¼æ以è¿ä¸ä¼å¸¦ æ¥ä»»ä½è¿è¡æ¶å¼éãç¶èï¼è¿ç§æ¹æ³ä¾æ§å 许 C ç¼è¯å¨æ¥çåå ç代ç ï¼å¹¶æ£æ¥å®çæ£ ç¡®æ§ (è¯æ³ï¼ç±»åï¼ç¬¦å·å¼ç¨ï¼çç)ãå æ¤ï¼å¦ææ¡ä»¶ä¸æ»¡è¶³ï¼ä»£ç åå çå¼ç¨ç¬¦å·å°± ä¸åå¨æ¶ï¼ä½ è¿æ¯å¿ é¡»å»ç¨ #ifdefã å¨ä»»ä½ææä¹ç #if æ #ifdef åçæ«å°¾ (è¶ è¿å è¡ç)ï¼å¨ #endif åä¸è¡çåé¢åä¸ æ³¨è§£ï¼æ³¨éè¿ä¸ªæ¡ä»¶è¡¨è¾¾å¼ãä¾å¦ï¼ .. code-block:: c #ifdef CONFIG_SOMETHING ... #endif /* CONFIG_SOMETHING */ éå½ I) åè ------------------- The C Programming Language, 第äºç ä½è ï¼Brian W. Kernighan å Denni M. Ritchie. Prentice Hall, Inc., 1988. ISBN 0-13-110362-8 (软ç®), 0-13-110370-9 (硬ç®). The Practice of Programming ä½è ï¼Brian W. Kernighan å Rob Pike. Addison-Wesley, Inc., 1999. ISBN 0-201-61586-X. GNU æå - éµå¾ª K&R æ ååæ¤ææ¬ - cpp, gcc, gcc internals and indent, é½å¯ä»¥ä» https://www.gnu.org/manual/ æ¾å° WG14 æ¯ C è¯è¨çå½é æ ååå·¥ä½ç»ï¼URL: http://www.open-std.org/JTC1/SC22/WG14/ Kernel process/coding-style.rstï¼ä½è greg@kroah.com åè¡¨äº OLS 2002ï¼ http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/