我對C函數指針的編程有着愛/恨的關係。我主要與閃存空間有限的微控制器一起工作,所以顯然我對使用優化感興趣。一方面,功能指針讓我的生活變得如此簡單,因爲我可以編寫一個硬件便攜式軟件模塊,用戶可以在其中提供用於執行硬件相關事情的功能回調(例如:用戶回調以將字節寫入串行端口)。通過這種方式,我可以編寫95%獨立於平臺的代碼,然後快速轉向新硬件。C編程。爲什麼函數指針會破壞優化
在另一方面,我注意到,很多編譯器的優化拋出窗外時,他們看到的任何使用函數指針。例如,我編寫了一個相當通用的函數,它接受一個枚舉類型作爲參數,然後爲每個枚舉類型選擇配置一個巨大的switch/case語句來配置寄存器等,具體取決於用戶傳遞給函數的枚舉類型。用一個不變的文字調用這個函數一次,IE永遠不會改變。構建好的二進制代碼似乎包含了操作代碼來處理每個開關/案例選擇,即使除了其中一個案例選擇都應該被視爲「死代碼」。我使用了不同的優化設置,但爲了得到最小的二進制文件,我必須完全註釋掉每個「case」塊,除了我需要的塊外,這會減少大約1k字節的Flash利用率。如果我不使用函數指針,那麼優化此代碼沒有問題。
奇怪的是,我從來沒有用在我與功能的原型代碼的函數指針。對於我用過的函數指針原型,指針在啓動時建立了一次靜態函數,然後再也不會再次(另一個常量字面賦值)。我知道我大概可以用#defines來完成相同的設計目標,但是讓我感到厭煩的是,這些工具無法根據我的代碼來解釋什麼是可能的/不可能的。
我能看到你有一個函數指針的情況下,和一些動態的東西,你不能預測執行功能(即一個人的類型爲終端,你不先進知道什麼爭論會是)。
有沒有什麼好的理由編譯器掙扎時,函數指針的使用,甚至在可預見的方式來優化?
編譯器停留在DWIS(做我所說)和DWIM(做我的意思)之間。你的函數的代碼說這個函數可以用許多可能的參數值調用,並且應該根據它的調用方式做不同的事情。您的實際使用情況要簡單得多。編譯器的生命是不可能的,除非它完成了「整個程序優化」,因爲它不能告訴你何時可以改變函數的調用方式。函數指針的靈活性會帶來成本。不具有功能指針的靈活性帶來不同的成本。 '太好玩了! –
我認爲這個問題需要示例代碼片斷,它們都帶有或者沒有函數指針,這些函數指針演示了優化問題。 – hyde