我寫在那裏我使用math.h
Ruby的C擴展。它正在OSX和Windows上編譯。在Windows下,我使用了Visual Studio Express C++ 2010附帶的nmake
。如何在C中定義一個函數,如果它之前沒有定義過?
我發現VS在其math.h
中沒有包含round()
函數。所以我說這個補償:
static inline double round(double value)
{
return floor(value + 0.5);
}
這偏離航向OSX下編譯爲round()
沒有被定義時導致了錯誤。 (實際的錯誤,我想我會宣佈我的是靜態的,它已經被宣佈非靜態版本之後。
無論如何,我想,以避免重新定義的函數,如果它確實存在。
在那一刻我有這樣的條件:?
#ifdef _WIN32
static inline double round(double value)
{
return floor(value + 0.5);
}
#endif
,在我的情況下工作 - 但它似乎有點一般我的意思是,如果我編譯Windows下
所以我的問題是不同的編譯器,我可以檢測一個函數是否已經被定義,並且那麼避免自己定義它?
或者,我可以檢測具體的編譯器nmake
使用 - cl
我認爲這是什麼?
我想我最好能函數是否已經定義檢測,因爲它似乎是最可靠的方法。
我擔心的是,如果我例如更新Visual Studio和'math.h'然後包含'round()' - 那麼就會像OSX下有衝突。這就是爲什麼我認爲檢查功能而不是環境是一個更好的主意。這是我從web開發中進行思考的一個思路,您可以在其中測試功能而不是嗅探用戶代理字符串。 – thomthom 2012-03-08 21:22:05
@ thomthom:是的,但這不是web開發=)。一般來說,你就是這樣做的。有時候當你改變編譯器的時候,事情就會崩潰,你需要修復它們,但是大部分情況下都可以避免它。在這種情況下,C99中增加了「round」。 VS不支持C99,這就是它不存在的原因。 – 2012-03-08 21:26:37
GNU的autoconf使用基於特徵的方法,#定義形式爲'HAVE_feature'的常量。例如,你可以定義'HAVE_ROUND'。由於在這種情況下它依賴於編譯器,因此可以在編譯命令的C預處理器定義中執行「-DHAVE_ROUND = 0」。在具有round()的編譯器中將其保留爲undefined。 round()函數的包裝將讀取'#if defined(HAVE_ROUND)&&!HAVE_ROUND ...函數聲明...#endif'。 – 2012-03-09 05:09:00