BMXXBP0400
很多事不深入以為自己懂了,但真正用到項目上,才發現了問題。曾以為自己寫C語言已經輕車熟路了,特別是對軟件文件的工程管理上,因為心里對自己的代碼編寫風格還是有自信的。(畢竟剛畢業時老大對我最初的訓練就是編碼格式的規范化處理)
曾以為,一個.c文件對應一個.件,.c文件只包含它自身的.件就好,若.c文件中用到其他文件中的內容,則.件把用到的頭文件包含進來就可以了。
自己貌似一直秉承這個理念在進行代碼編寫(好可怕)。工程文件數量小時,這種理念貌似看不出問題,但隨著工程文件數量越來越多,我發現自己這種思路有了弊端:頭文件互相包含,導致編譯時自以為有些宏變量聲明了,它就能起作用,但實際測試發現這種方式編碼后,有些聲明的宏沒能起到作用。
經過領導及同事的指正,自己才明白原有的代碼編寫習慣不正確。應該秉承.c文件對應的.件只包含頭文件里用到的其它文件的頭文件,任何非必須的.件不要包含;而.c文件里面要包含用到的所有.件。這樣寫即使存在.c文件內頭文件重復包含也不傷大雅。
語言描述有時太抽象,還是符號舉例說明下:假如有兩個.c文件分別為A.c和B.c,自然它們都有各自的A.h和B.件。
原有的思路:
A.c里面只有一個#include “A.h”,而A.h所包含的就是一大堆如B.h,C.h,D.h.。..。文件,因為A.c文件里面要用到B.h,C.h,D.h里面的內容。如圖一所示。
新思路:
A.h里面只包含A.h所寫內容要用到的.件,很多時候A.h里面無需任何.件。而在A.c文件內就要寫成 #include “B.h” #include “C.h” #include “D.h”。而且兩個文件的.c文件在頭文件包含上可以互相包含。如圖二所示。
項目中遇到的這個頭文件包含問題導致我重新搜索資料進行該問題的深入了解,故下文是通過網絡資源的搜查及加上自己對它的理解,進行了相關內容的整理,希望對感興趣的小伙伴有所幫助。
背景
對于C語言來說,頭文件的設計體現了大部分的系統設計。不合理的頭文件布局是編譯時間過長的根因,不合理的頭文件實際上不合理的設計。
依賴
特指編譯依賴。若x.h包含了y.h,則稱作x依賴y。依賴關系會進行傳導,如x.h包含y.h,而y.h又包含了z.h,則x通過y依賴了z。依賴將導致編譯時間的上升。
雖然依賴是不可避免的,也是必須的,但是不良的設計會導致整個系統的依賴關系無比復雜,使得任意一個文件的修改都要重新編譯整個系統,導致編譯時間巨幅上升。
在一個設計良好的系統中, 修改一個文件,只需要重新編譯數個,甚至是一個文件。
某產品曾經做過一個實驗,把所有函數的實現通過工具注釋掉,其編譯時間只減少了不到10%,究其原因,在于A包含B, B包含C, C包含D,最終幾乎每一個源文件都包含了項目組所有的頭文件,從而導致絕大部分編譯時間都花在解析頭文件上。
某產品更有一個“優秀實踐”,用于將.c文件通過工具合并成一個比較大的.c文件,從而大幅度提高編譯效率。
其根本原因還是在于通過合并.c文件減少了頭文件解析次數。但是,這樣的“優秀實踐”是對合理劃分.c文件的一種破壞。
大部分產品修改一處代碼,都得需要編譯整個工程,對于TDD之類的實踐,要求對于模塊級別的編譯時間控制在秒級,即使使用分布式編譯也難以實現,最終仍然需要合理的劃分頭文件、以及頭文件之間的包含關系, 從根本上降低編譯時間。
《google C++++ Style Guide》 1.2 頭文件依賴 章節也給出了類似的闡述:若包含了頭文件aa.h,則就引入了新的依賴:一旦aa.h被修改,任何直接和間接包含aa.h代碼都會被重新編譯。如果aa.h又包含了其他頭文件如bb.h,那么bb.h的任何改變都將導致所有包含了aa.h的代碼被重新編譯。
在敏捷開發方式下,代碼會被頻繁構建,漫長的編譯時間將極大的阻礙頻繁構建。因此,我們傾向于減少包含頭文件,尤其是在頭文件中包含頭文件,以控制改動代碼后的編譯時間。
合理的頭文件劃分體現了系統設計的思想,但是從編程規范的角度看,仍然有一些通用的方法,用來合理規劃頭文件。本章節介紹的一些方法,對于合理規劃頭文件會有一定的幫助。
原則1:頭文件中適合放置接口的聲明,不適合放置實現。
說明:頭文件是模塊( Module)或單元( Unit)的對外接口。頭文件中應放置對外部的聲明,如對外提供的函數聲明、宏定義、類型定義等。
內部使用的函數(相當于類的私有方法)聲明不應放在頭文件中。
內部使用的宏、枚舉、結構定義不應放入頭文件中。
變量定義不應放在頭文件中,應放在.c文件中。
變量的聲明盡量不要放在頭文件中,亦即盡量不要使用全局變量作為接口 。變量是模塊或單元的內部實現細節,不應通過在頭文件中聲明的方式直接暴露給外部,應通過函數接口的方式進行對外暴露。
BMXXBP0400
CONTROL TECHNIQUES UNI-3405 USPP UNI3405
SYMAX 8030-CRM-565 NSFP 8030CRM565
TB WOODS UVC-4050-0H USPP UVC40500H
PHOENIX CONTACT IBS-IP-500-PS-2-BS USPP IBSIP500PS2BS
CUTLER HAMMER ND312WK USPP ND312WK
HARMONIC DRIVE HTL8000-1L-AS-DC USPP HTL80001LASDC
MICROMASS LCT USPP LCT
REXROTH 0-608-830-123 USPP 0608830123
GE FANUC IC3600LSRB1 NSPP IC3600LSRB1
ALLEN BRADLEY 1336E-B060-AE-EN-HA2-L8E USPP 1336eB060AE
KEYENCE CORP LC-2400W USPP LC2400W
CUTLER HAMMER XKDN400B USPP XKDN400B
ALLEN BRADLEY 1395-A70-D2-P10-P54EN USPP 1395A70D2P10P5
PEAK SCIENTIFIC NM30LA USPP NM30LA
SIEMENS 6ES7-318-2AJ00-0AB0 NSFP 6ES73182AJ000AB0
SQUARE D PEF361600LSG100 USPP PEF361600LSG100
TELEMECANIQUE ATV-66D54-N4U USPP ATV66D54N4U
MICROSWITCH LSH6A NSFP LSH6A
ALLEN BRADLEY 1756-L55M13 FNFP 1756L55M13
CUTLER HAMMER NC31200WK USPP NC31200WK
RELIANCE ELECTRIC 803613-SC USPP 803613SC
SAGINAW MACHINE CO 000W544817 NSPP 000W544817
ALLEN BRADLEY 501564 NSPP 501564
SIEMENS 6ES7-417-4HL00-0AB0 USPP 6ES74174HL000AB0
ALLEN BRADLEY 8520-3S5A-BAT-EX4-T1-Y-4-5-7 USPP 85203S5
ALLEN BRADLEY 1785-L20C USPP 1785L20C
SIEMENS 6FM1-726-3BA00 NSPP 6FM17263BA00
ADEPT TECH 30332-22350 USPP 3033222350
ALLEN BRADLEY 1336S-BX060-AN-EN4 USPP 1336SBX060ANEN4
BAILEY CONTROLS IMMFP-02 NSPP IMMFP02
FOXBORO P0960AW USPP P0960AW
GENERAL ELECTRIC THPC3640BG3TRT1 USPP THPC3640BG3TRT1
SIEMENS 6EC1-652-0A USPP 6EC16520A
ALLEN BRADLEY 1336S-B125-AN-EN USPP 1336SB125ANEN
GE FUJI 6KDV3400Q2B20 NSFP 6KDV3400Q2B20
BURTON MCD-61407/94629 NSPP MCD6140794629
BOSCH HYDRAULIC 1070075976 USPP 1070075976
TELEMECANIQUE CR3HB12F21 NSFP CR3HB12F21
KEB COMBIVERT 23.F4.C1R-3410 NSPP 23F4C1R3410
RELIANCE ELECTRIC UGZ3455 USPP UGZ3455
RELIANCE ELECTRIC UVZC3007 USPP UVZC3007
ALLEN BRADLEY 1334-FOB-T4 USPP 1334FOBT4
BOSCH 047826-312 USPP 047826312
ASEA BROWN BOVERI 52614759 NSFP 52614759
ALLEN BRADLEY 5250-LP1 USPP 5250LP1
RELIANCE ELECTRIC 45C-301A NSFP 45C301A
ASEA BROWN BOVERI ACS800-U1-0140-5-B056-L503-P901 USPP
CUTLER HAMMER HNB31200T USPP HNB31200T
ALLEN BRADLEY 500-GOB-930 USPP 500GOB930
ALLEN BRADLEY 1392-B100-RK-MC-B-F2 USPP 1392B100RKMCBF2
SIEMENS 6RA7-000-0MV62-0 USPP 6RA70000MV620
GENERAL ELECTRIC GESB1200A USPP GESB1200A
WESTINGHOUSE 55B6621A3Y USPP 55B6621A3Y
ALLEN BRADLEY 1756-L55M14 NSFP 1756L55M14
INDRAMAT DDC01.2-N100A-DS01-02-FW USPP DDC012N100ADS010
RELIANCE ELECTRIC SA3000DC140 USPP SA3000DC140
RELIANCE ELECTRIC SA3000DC17.5 USPP SA3000DC175
RELIANCE ELECTRIC SA3000DC70 USPP SA3000DC70
LAMBDA LCS-E-5-OV USPP LCSE5OV
FANUC A06B-6064-H322-H550 USPP A06B6064H322H550
ALLEN BRADLEY 1336-B100-EAH-L3 USPP 1336B100EAHL3
SQUARE D PXF362000 USPP PXF362000
ALLEN BRADLEY 1336VT-B060-EAS-L3 USPP 1336VTB060EASL3
ALLEN BRADLEY 8520-1S10A-BAT-EX4-T1-Y-4-5-7 USPP 85201S
ALLEN BRADLEY 6180-DIIEHLDRECZ USPP 6180DIIEHLDRECZ
ALLEN BRADLEY 4100-212-P USPP 4100212P
GENERAL ELECTRIC 9T83B3036 NSFP 9T83B3036
ALLEN BRADLEY 1336S-B075-AN-EN4-HA1-L6 USPP 1336SB075AN
BALDOR ZD18H-475-EO USPP ZD18H475EO
TEXAS INSTRUMENTS 575-2103 NSFP 5752103
MEASUREX 053629-00 USPP 05362900
MEASUREX 08546401 USPP 08546401
INDRAMAT DDC01.2-N100A-DS68-00-FW USPP DDC012N100ADS680
FANUC A06B-6041-H112 USPP A06B6041H112
ALLEN BRADLEY 1336E-B100-AA-EN-HA2-L9E USPP 1336EB100AA
SQUARE D NC36900 NSPP NC36900
CONTROL TECHNIQUES SPMD1604M USPP SPMD1604M
BALDOR KBM3456 NSFP KBM3456
ACCURAY 082157-002 USPP 082157002
GETTYS 110-114 USPP 110114
MOORE PRODUCTS 15799-209 USPP 15799209
MOORE PRODUCTS 15799-209R USPP 15799209R
ALLEN BRADLEY 5250-LP NSPP 5250LP
OMRON 3G8B3-CL001 NSFP 3G8B3CL001
BAILEY CONTROLS 6637033A USPP 6637033A
POWERTEC INDUSTRIAL MOTORS INC C0302N3CH109NNNN NSFP C0
SIEMENS 6SE9522-4DG40 USPP 6SE95224DG40
SIEMENS 6SE7-026-0ED61-Z NSFP 6SE70260ED61Z
ALLEN BRADLEY 1772-ME8 NSPP 1772ME8
TELEMECANIQUE TSX-P67425 USPP TSXP67425
WESTINGHOUSE 4256A11G01 USPP 4256A11G01
EPSON E2C351S-UL USPP e2c351sul
MARPOSS 3708630010 NSPP 3708630010
GE FANUC IC3600LRLB1 USPP IC3600LRLB1
MOORE PRODUCTS 39ACM24BCN USPP 39ACM24BCN
CONTROL TECHNIQUES SPMD1604S USPP SPMD1604S
KEYENCE CORP LS-5121 NSFP LS5121
TOSHIBA VT130H7U410KA NSFP VT130H7U410KA
RELIANCE ELECTRIC 803430-8S USPP 8034308S
YASKAWA ELECTRIC CIMR-SVJ-37AA USPP CIMRSVJ37AA
CUTLER HAMMER SV9050AS-2M0A00 USPP SV9050AS2M0A00
ALLEN BRADLEY 2750-AHPR NSFP 2750AHPR
SIEMENS 6AV76150AA120BG0 NSFP 6AV76150AA120BG0
OBARA CORP X-A-TC6576N-AL1-276-C USPP XATC6576NAL1276C
ALLEN BRADLEY 1336S-B060-AE-DE4 USPP 1336SB060AEDE4
FANUC A06B-6063-H215 NSFP A06B6063H215
INDRAMAT TWM1.1-100-300-W1 USPP TWM11100300W1
INDRAMAT TWM1.2-100-300-W1 USPP TWM12100300W1
SIEMENS 6ES5-926-3KA12 NSFP 6ES59263KA12
WESTINGHOUSE 149D944G01 USPP 149D944G01
SIEMENS 6AV1-222-0AD20 USPP 6AV12220AD20
HONEYWELL J-DSG53 USPP JDSG53
FANUC A06B-6064-H322 USPP A06B6064H322
INDRAMAT CLM1.3-X-0-2-B-FW USPP CLM13X02BFW
ALLEN BRADLEY 6170-DCCE1A1EBZZ USPP 6170DCCE1A1EBZZ
ALLEN BRADLEY 6170-ECFD1A1EBZZ USPP 6170ECFD1A1EBZZ
ALLEN BRADLEY 6170-EDCD1Z1EBZZ/A USPP 6170EDCD1Z1EBZZA
ALLEN BRADLEY 6170-EDD1A1EBZZ/A USPP 6170EDD1A1EBZZA
ALLEN BRADLEY 6170-FDCF-1A1ECZZ USPP 6170FDCF1A1ECZZ
FISHER ROSEMOUNT 880A USPP 880A
TELEMECANIQUE ATV-66D46-N4U USPP ATV66D46N4U
ALLEN BRADLEY 1785-L40E/E USPP 1785L40EE
ALLEN BRADLEY 150-B240NBDB USPP 150B240NBDB
GE FANUC IC3600LSRB1 USPP IC3600LSRB1
MODICON MMPMT24T0C NSFP MMPMT24T0C
RELIANCE ELECTRIC 19C401 USPP 19C401
ESC S-112-0000 USPP S1120000
ESC S-112-0001 USPP S1120001
ALLEN BRADLEY 143678 NSFP 143678
ASEA BROWN BOVERI GNT2009459R0007 NSFP GNT2009459R0007
ALLEN BRADLEY 150-A135NBD NSFP 150A135NBD
GE FANUC IC646MBP001 FNFP IC646MBP001
ALLEN BRADLEY 1336S-B050-AA-EN-HA2 USPP 1336SB050AAENHA
ALLEN BRADLEY 1336S-BX060-ANEN4-L6 USPP 1336SBX060ANEN4
SQUARE D NX-36600 USPP NX36600
INDRAMAT MAC112B-0-GD-4-C/130-A-1/W1518LV/S021 USPP MAC
GIDDINGS & LEWIS 502-04112-11R5 USPP 5020411211R5
ALLEN BRADLEY 1775-SR5 NSFP 1775SR5
ALLEN BRADLEY 1336F-B050-AN-EN USPP 1336FB050ANEN
RELIANCE ELECTRIC 0-52842 NSFP 052842
ALLEN BRADLEY 1756-M3 NSFP 1756M3
HONEYWELL 51196886-100 NSFP 51196886100
SIEMENS 6FM1-726-3BA00 USPP 6FM17263BA00