2009年12月7日 星期一

Include guard VS. #pragma once

一個簡單的小觀念,卻是我工作以後才開始的習慣-Include guard
Include guard解決了大型專案修改時,牽一髮動全身的already be defined問題(同一個header被include兩次在c++是不合法的)。另外還有一招叫作#pragma once 有同樣的效果,不同點在於它是用”物理”的檔案位置來避免重複include。所以今天如果專案裡有兩份"一模一樣'"的header file,就…還是會出包。稍微比較一下兩種方法的優缺點。


Include guard

優點:
1. 標準compiler都有支援,code的長久性跟porting的泛用性較佳。
缺點:
1. include naming 撞衫:可能今天取的#ifndef __flash_H__跟用到的SDK某檔案同名。
2. compiler時間較長 。

#pragma once

優點:
1. Compiler較快。
2. 沒有撞衫的問題。
缺點:
1. 舊一點的compiler可能不支援。
2. 無法防範兩份一模一樣的檔案在不同位置重複include的問題。

選哪一個!?

我目前還是習慣在創造header file時乖乖加上#ifndef, #define。但今天試想某個case。
大型專案有人稍微修改了一份幾乎一模一樣的header file然後粗心duplicate了兩份,又commit卻忘了實際上自己linking的還是原本header file產生的dll。
結果因為.h不match(後改的.h先被include到了)跑出了一些鬼打牆又很難確定問題點的bug(compiler都過了,卻在run time有問題)。以這個case來說#pragma once的缺點似乎變成優點了?至少兩份幾乎一樣的檔案造成的linking error比較容易發現且好修正。
不知道還有甚麼優缺點沒考慮到,Objective-C 用的是#import,是不是不用煩惱這些?實際上是怎麼作到include each file only once呢?(偏向#progma once?),是不是也會有類似討厭危險的地方需要小心?

2 則留言: