簡體   English   中英

未使用功能的功能原型

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM