¿Por qué C proporciona "enlaces" de lenguaje donde C ++ se queda corto?

59

Hace poco me pregunté cuándo usar C sobre C ++ y viceversa. Afortunadamente, alguien ya me venció y aunque tomó un tiempo, pude digerir todas las respuestas y comentarios a esa pregunta.

Sin embargo, un elemento de esa publicación sigue abordándose una y otra vez, sin ningún tipo de ejemplo, verificación o explicación:

  

"El código C es bueno para cuando quieres tener enlaces de varios idiomas para tu biblioteca"

Eso es una paráfrasis. Debo tener en cuenta que varias personas señalan que las vinculaciones de múltiples idiomas son posibles en C ++ (a través de algunos extern en funcionamiento), pero sin embargo, si lees esa publicación en su totalidad, es bastante obvio que C es ideal para la vinculación de portabilidad / idioma. Mi pregunta es: why?

¿Alguien puede proporcionar razones concretas por las que escribir bibliotecas en C permita enlaces y portabilidad más fáciles en otros idiomas?

    
pregunta smeeb 04.05.2015 - 12:03

8 respuestas

70

C tiene una interfaz mucho, mucho más simple, y sus reglas para convertir una interfaz de código fuente en una interfaz binaria son lo suficientemente simples como para generar interfaces externas para enlazarlas de una manera bien establecida. C ++, por otro lado, tiene una interfaz increíblemente complicada, y las reglas para el enlace ABI no están estandarizadas en absoluto, ni formalmente ni en la práctica. Esto significa que prácticamente cualquier compilador para cualquier lenguaje para cualquier plataforma puede vincularse con una interfaz C externa y saber exactamente qué esperar, pero para una interfaz C ++, es esencialmente imposible porque las reglas cambian según el compilador, la versión y el software. plataforma con la que se construyó el código C ++.

  

En C, no hay reglas de implementación de lenguaje binario estándar,   cualquiera, pero es un orden de magnitud más simple y en la práctica   Los compiladores usan las mismas reglas. Otra razón por la que el código C ++ es difícil   depuración es la gramática complicada mencionada anteriormente, ya que los depuradores   Con frecuencia no se pueden manejar muchas características del idioma (coloque puntos de interrupción).   en las plantillas, analice los comandos de conversión de punteros en las ventanas de visualización de datos,   etc.).

     

La falta de un ABI estándar (interfaz binaria de aplicación) tiene otro   consecuencia - hace que las interfaces de envío de C ++ a otros equipos /   los clientes no son prácticos ya que el código de usuario no funcionará a menos que sea   Compilado con las mismas herramientas y opciones de compilación. Ya hemos visto   Otra fuente de este problema: la inestabilidad de las interfaces binarias.   Debido a la falta de encapsulación en tiempo de compilación.

     

- C ++ defectuoso

    
respondido por el Mason Wheeler 04.05.2015 - 12:28
31

Si está intentando comunicarse con un hablante de otro idioma, pidgin es más fácil que el inglés de Shakespeare.

Los conceptos de

C (llamadas de función, punteros, cadenas terminadas en NULL) son muy sencillos, por lo que otros lenguajes pueden implementarlos lo suficientemente bien como para llamar a las funciones C. Por razones históricas, muchos otros lenguajes se implementan en C, lo que facilita aún más la tarea de llamar a C

C ++ agrega bastante cosas: clases, con herencia y vtables y modificadores de acceso; excepciones, con el despliegue de la pila y el cambio del flujo de control; plantillas. Todo esto hace que sea más difícil para otros lenguajes usar enlaces C ++: en el mejor de los casos, hay más "pegamento" o código de interoperabilidad para implementar, y en el peor, los conceptos no se traducen directamente (debido a las diferencias en los modelos de clase, el manejo de excepciones, etc.). Para las plantillas en particular, simplemente usarlas (crear instancias) normalmente requiere un paso de compilación con un compilador de C ++, que enormemente complica su uso desde otros entornos.

Dicho todo esto, es posible exagerar la dificultad de proporcionar enlaces de una biblioteca de C ++ a otro idioma:

  • Los enlaces de C ++ pueden ser tan compatibles como C, si estás dispuesto a trabajar en ello. Como @DeadMG señala, C ++ admite extern "C" , por lo que puede exportar enlaces de lenguaje de estilo C (con toda la simplicidad y compatibilidad de los enlaces de C) desde una biblioteca de C ++ (con la limitación de que no puede exponer ningún C ++ - funcionalidad específica).
  • Otra objeción común a los enlaces de lenguaje C ++ es la falta de estabilidad ABI para C ++, pero esto también está exagerado; Los ABI de C ++ están menos estandarizados que los ABI de C, pero existen estándares y estándares de facto (el ABI de It ++ de C ++, que también se usa en OS X ; estándar de facto de GCC para Linux). Windows es peor, pero incluso en Windows, permanecer dentro de una versión de Visual C ++ debería funcionar bien.
respondido por el Josh Kelley 04.05.2015 - 14:58
21

C es uno de los idiomas más antiguos que existen. Su ABI es simple, y prácticamente todos los sistemas operativos que todavía están en uso se han escrito en ella . Mientras que algunos de esos sistemas operativos pueden haber agregado cosas, por ejemplo. en C # / .NET o en la parte superior, abajo están muy empapados en C.

Eso significa que, para utilizar la funcionalidad provista por el sistema operativo, prácticamente todos los lenguajes de programación necesitan una forma de interactuar con las bibliotecas de C de todos modos . Perl, Java, C ++, todos ellos de forma nativa proporcionan formas de "hablar C", porque tenían que hacerlo si no querían reinventar cada rueda individual que hay.

Esto hace que C sea el latín de los lenguajes de programación. (¿Cuántos años de Internet antes de esa metáfora tiene que ser "el inglés de los lenguajes de programación"?)

Cuando escribes tu biblioteca en C, obtienes una interfaz compatible con C de forma gratuita (obviamente). Si está escribiendo su biblioteca en C ++, puede obtener enlaces C, a través de las declaraciones extern "C" que mencionó.

Sin embargo , puede obtener esos enlaces solo para la funcionalidad que puede expresarse en C .

Por lo tanto, la API de su biblioteca no puede hacer uso de ...

  • plantillas,
  • clases,
  • excepciones,
  • cualquier función tomando o devolviendo objetos.

Un ejemplo simple, necesitaría hacer que las funciones exportadas tomen y devuelvan las matrices ( [] ) en lugar de std::vector (o std::string para eso) materia).

Por lo tanto, no solo no podría proporcionar ninguna de las cosas buenas que C ++ tiene para ofrecer a los clientes de su biblioteca, sino que también tendría que hacer un esfuerzo adicional para "traducir" el API de su biblioteca. de C ++ a "C compatible" ( extern "C" ).

Es por eso que el punto podría señalarse que C es la mejor opción para implementar una biblioteca. Personalmente, creo que los beneficios de C ++ aún superan el esfuerzo necesario para un extern "C" API, pero eso es solo para mí.

    
respondido por el DevSolar 04.05.2015 - 17:15
6

Dejando de lado los detalles que otras respuestas ya proporcionan:

La razón por la que tantos idiomas proporcionan un enlace C es que todos los sistemas operativos * nix y Windows exponen la mayor parte de la API de su sistema operativo a través de una interfaz C. Por lo tanto, la implementación del lenguaje ya necesita interactuar con C para poder ejecutarse en los principales sistemas operativos. Por lo tanto, es sencillo ofrecer también la comunicación directa con cualquier interfaz C desde el propio idioma.

    
respondido por el Martin Ba 04.05.2015 - 16:10
5

No hay razón. Si la semántica que intenta expresar es fundamentalmente compatible con C y no es algo como plantillas, no hay razón por la que pueda vincularse más fácilmente si la implementación está escrita en C. De hecho, es bastante por definición que una interfaz C puede completarse con cualquier implementación que cumpla con el contrato binario, incluida una implementación en otro idioma. Hay otros lenguajes distintos de C ++ que pueden implementar contratos binarios C que pueden funcionar de esta manera.

A lo que realmente se reduce es a las personas que no quieren aprender nuevos idiomas o ideas que tienen semánticas o funciones realmente útiles que intentan desesperadamente elegir cualquier motivo para permanecer en la era de los dinosaurios.

    
respondido por el DeadMG 04.05.2015 - 12:17
2

Hay dos ejes principales al interactuar con otro idioma:

  • los conceptos que la interfaz puede traspasar: ¿solo valores? referencias? genéricos?
  • cómo se implementa la interfaz en "binarios" (llamado ABI)

C tiene una ventaja sobre C ++ en esos dos frentes:

  • C solo tiene conceptos en su mayoría simples, que aparecen en la mayoría de los demás idiomas 1
  • Los binarios de ABI de C se deciden por el sistema operativo 2

Ahora, por qué la mayoría de los idiomas tienen un conjunto de conceptos similar al que C puede deberse a que sea "simple" o "preexistente"; Sin embargo, no importa, el punto es que sí.

Por el contrario, C ++ tiene conceptos complejos, y cada compilador decide la ABI (aunque muchos se adhieren a la ABI de Itanimum, excepto en Windows ...). En realidad, hubo una propuesta de Herb Sutter para que los sistemas operativos corrigieran un ABI de C ++ (en función de cada sistema operativo) para solucionar parcialmente este problema. Además, se debe tener en cuenta que es posible un FFI de C ++, D lo está intentando 3 .

1 Excepto variadics ( ... ), no son simples

2 ¿C tiene un ABI estándar?

3 Interfaz D al código de C ++ heredado

    
respondido por el Matthieu M. 05.05.2015 - 17:41
0

Fundamentalmente, todo se reduce a la estandarización ABI. Si bien ni C ni C ++ tienen un ABI estandarizado que otros idiomas pueden usar para interactuar entre binarios escritos, C se ha convertido en un estándar de facto, todos lo saben y todos los demás pueden usar las mismas reglas simples que tiene el lenguaje con respecto a tipos y llamadas a funciones.

C ++ podría tener un ABI estándar, pero Stroustrup ha dicho que no ve la necesidad de uno. También dice que sería difícil obtener el consenso de los escritores de compiladores (aunque dudo que el comité estándar de C ++ emitiría un ABI similar a los existentes y los escritores de compiladores simplemente alterarían la próxima versión de sus compiladores, que en ocasiones son incompatibles con los binarios). construidas con versiones antiguas de sus compiladores de todos modos - recuerdo haber recompilado un par de bibliotecas con un nuevo compilador de Sun y encontrar que fallaron en trabajar con las antiguas)

Notará que algunas compañías han optado por utilizar un ABI estándar, Microsoft comenzó este proceso con COM en los años 90, y hoy lo han refinado en el ABR de WinRT (no debe confundirse con el otro). WinRT (que se refiere a un tipo de sistema operativo de mesa) que permite que los programas escritos en C # se comuniquen con bibliotecas escritas en C o C ++ (es decir, la capa del sistema operativo de Microsoft está escrita en C ++, expuesta mediante WinRT y consumida por las aplicaciones de C # cuando llaman a cualquier tiempo de ejecución del sistema operativo rutina)

No hay mucho que alguien pueda hacer a menos que un organismo de normalización se encargue de solucionar esta situación. Microsoft obviamente ve el valor en él y ha tomado medidas para resolverlo para su plataforma.

Entonces la respuesta es realmente C no proporciona enlaces de idioma. Sucede que nadie los ha escuchado y los consume a pesar de todo.

    
respondido por el gbjbaanb 06.05.2015 - 10:01
-2

Todas las respuestas no llegan al problema real: la compilación en C ++ introduce el "nombre de los nombres", por lo que los binarios son incompatibles con las llamadas a funciones "simples".

Todo lo relacionado con ABI es poco más que un intento de estandarizarlo.

En general, no está garantizado que pueda enlazar funciones compiladas con diferentes compiladores, incluso si se mantiene en C ++ simple. Anteriormente estaba seguro de que eran incompatibles, pero hoy en día la estandarización se está arrastrando;)

OTOH C fue diseñado precisamente para ser un "ensamblaje de alto nivel" y permitir todo tipo de interfaz fácil. No debería sorprender que se adapte mejor al gusto entre idiomas.

Nota al margen: el compilador original de C ++ (cfront) en realidad produjo la fuente de C que se tuvo que compilar, exactamente como gcc que produce el ensamblaje "bajo el capó".

    
respondido por el ZioByte 06.05.2015 - 12:04

Lea otras preguntas en las etiquetas