[英]Function prototype for unused function
我正在編寫一段代碼,該代碼將用於多個項目,並且我剛剛意識到,如果函數的調用受if的保護,我只能擁有函數原型(沒有實際的實現)。 樣品:
#ifndef __TEST_H
#define __TEST_H
uint32_t test_init(void);
#if CONFIG_TEST
bool is_test_supported(void);
#else
static inline bool is_test_supported(void)
{
return false;
}
#endif
#endif
在C文件中
...
if (is_test_supported())
test_init();
...
在未定義CONFIG_TEST的系統上,上面的代碼仍然可以正常編譯。 我可以想象這是因為編譯器足夠聰明,可以理解永遠不會執行代碼路徑,這是正確的,並且這種行為可移植嗎? 編譯器是clang。
編輯:更正了函數名稱上的一些錯誤...
形式上,函數test_init
用於代碼中,並且語言需要定義。
但是,智能編譯器可能會找出從未執行過if
的分支,並消除了對test_init
的調用。 如果編譯器消除了對該函數的所有調用,則典型實現可能無法診斷問題,因為該函數實際上並未使用。 具有外部鏈接的實體的“缺少定義”問題通常在鏈接階段進行診斷。 當鏈接器無法將函數調用與函數定義匹配時,將報告該錯誤。 如果沒有電話,則無需匹配任何內容。
但是,再次,這不是您可以依靠的東西。 在語言級別上,沒有諸如“靜態if”之類的功能。 正式的C語言不允許你離開這樣的功能定義,即使它們被保護的if
因病情在編譯時是已知的。
if
要刪除函數調用, 則不能依賴簡單的C。 碰巧編譯器優化了測試
if(test_is_supported())
至
if(false)
通過內聯,然后進一步將后續的test_init()
優化為test_init()
代碼。
但是 , 不能保證這些優化。 例如,如果編譯時沒有優化,則很有可能不會發生優化,並且會生成函數調用。 在這種情況下,即使鏈接器從不執行,也將需要該函數的定義,否則它將失敗。
比較安全的方法是使用#if
完全刪除代碼:
#if CONFIG_TEST
if(test_is_supported())
test_init();
#endif
如果未定義CONFIG_TEST
(即,如果未定義test_init()
則這將確保根本不編譯if
和后續代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.