Ni GCC ni Clang cumplen el estándar de C++ en el enlace de lenguajes

Fuentes: neither gcc nor clang are compliant with standard c++

En C++, los tipos de función llevan asociado un «enlace de lenguaje» (language linkage) que puede ser «C++», «C» u otro definido por la implementación. El estándar establece con claridad que dos tipos de función con enlaces de lenguaje distintos son tipos diferentes aunque su firma sea idéntica, precisamente porque algunas implementaciones podrían usar convenciones de llamada distintas para C y C++ y no deben mezclarse.

Sin embargo, ni GCC ni Clang almacenan esa información de enlace dentro del tipo. El resultado es que, para ambos compiladores, una función declarada con extern "C" y otra declarada como función C++ pura pueden llegar a ser exactamente el mismo tipo. El usuario lo demuestra con un ejemplo: un static_assert(std::is_same<c_func, void ()>::value) que debería fallar porque c_func está marcada como extern "C" y, por tanto, no debería ser idéntica a void (), pero tanto GCC como Clang lo aceptan.

Esta omisión también provoca fallos de compilación incorrectos al sobrecargar funciones que toman punteros a función: declarar dos void f cuyas únicas diferencias son el enlace de lenguaje del parámetro lleva a ambos compiladores a considerar los parámetros idénticos y, por tanto, a denunciar una violación de la regla de la definición única (ODR), cuando en realidad se trata de firmas distintas.

El autor considera que la culpa no recae en los compiladores, sino en el estándar: debería declarar este comportamiento como definido por la implementación. Cambiarlo ahora en GCC o Clang sería una rotura de ABI, porque los nombres «manglados» de los tipos de función extern "C" deberían empezar a codificar el enlace de lenguaje, y no hay incentivo para hacerlo: las convenciones de llamada de C y C++ son idénticas en prácticamente todas las plataformas existentes.