(つ`ω´)つ says to Ubuntu 台灣社群
GCC 與 Clang 都不符合 C++ 標準 (★ 45 分) C++ 標準規定,函式型別帶有「語言連結」(language linkage),例如 `C++` 或 `C`;即使參數與回傳值完全相同,只要語言連結不同,也應視為不同型別。這項規定是為了容納不同的呼叫慣例,避免以錯誤方式呼叫函式。文章指出,GCC 與 Clang 並未把語言連結資訊納入函式型別,因此會把 `extern "C"` 函式與一般 C++ 函式視為相同型別,導致型別判斷結果錯誤,也可能讓原本應能成立的函式多載被誤判為重複定義,觸犯一次定義規則(ODR, One Definition Rule)。 作者認為,問題未必應歸咎於 GCC 或 Clang,而是 C++ 標準本身的規定不切實際,應改成由實作自行決定。現今多數平台上的 C 與 C++ 呼叫慣例大致相同,編譯器若要完全遵循規範,可能必須把 `extern "C"` 的型別差異納入名稱修飾(name mangling),進而造成 ABI(二進位應用程式介面,Application Binary Interface)變更,破壞既有二進位檔的相容性。因此,編譯器實作者沒有太大動機改變已沿用多年的行為。 留言者指出,這類問題早在約 12 年前就曾出現在 C++ 標準委員會的議題中,但至今仍缺乏明確提案或缺陷報告(defect report)推動修正。部分討論認為,函式的呼叫慣例本來就應是型別的一部分;在 32 位元 x86 等平台上,使用錯誤呼叫慣例甚至可能破壞堆疊。也有人質疑作者把影響描述成 ABI 破壞,認為主要是原始碼層級的 API(應用程式介面,Application Programming Interface)變更;另一方則反駁,ABI 變更會迫使大量既有程式與編譯結果同步更新,衝擊更大。 更廣泛的討論集中在 C++ 的複雜性與系統程式設計的取捨。有人主張新專案可考慮 Rust、Zig 或 Odin,以減少記憶體安全與語言細節帶來的負擔;但反方認為,系統程式設計正是由呼叫慣例、硬體特性、配置器、效能與平台差異等細節構成,C++ 的彈性讓開發者能自行掌握這些取捨。Rust 與 Zig 的成熟度、GPU 開發對 C++ 生態系的依賴,以及嵌入式開發常使用不完全符合標準的 C++ 子集,也都被視為採用替代語言時必須面對的現實。整體而言,留言者一方面認同標準應提供跨編譯器的可攜性,另一方面也認為 GCC 與 Clang 的共同慣例已成為實務上不可忽視的最低相容基準。 👥 49 則討論、評論 💬 https://news.ycombinator.com/item?id=48970039