在 C++ 中,函式型別會與「語言連結」關聯:此連結可為「C++」、「C」,或由實作定義的其他語言。而標準明確指出,即使兩個函式型別在其他方面完全相同,只要語言連結不同,它們就是不同的型別。其概念是,某些實作可能會對 C++ 函式與 C 函式採用不同的呼叫慣例,因此兩者無法混用

然而 gcc 與 clang 並未將語言連結資訊儲存在型別中,因此具有不同語言連結的兩個函式可能被視為相同:

#include <type_traits>
extern "C" using c_func = void ();
// this static assertion should fail, but it doesn't
static_assert(std::is_same<c_func, void ()>::value);

這也可能導致在對接受函式指標參數的函式進行多載時發生錯誤的編譯失敗:

extern "C" using c_func = void ();
void f(c_func *) {}
void f(void (*)()) {}

上述程式碼應該可以編譯,但 gcc 與 clang 皆認為參數列表相同,因而違反單一定義規則

筆者認為,責任不在 gcc 或 clang,而在標準本身。也就是說,標準有誤,應將此行為改為實作定義。gcc 與 clang 無法改變其行為,因為這會造成 ABI 破壞(在名稱修飾中,extern "C" 函式型別的編碼方式會不同)。而且它們也沒有理由做出此改變:就筆者所知,在幾乎所有平台上,C 與 C++ 的呼叫慣例都是相同的