Je me demandais récemment quand utiliser C sur C ++ et vice versa. Heureusement, quelqu'un m'a déjà battu et, bien que cela ait pris du temps, j'ai pu digérer toutes les réponses et commentaires à cette question.
Toutefois, un élément de ce message continue à être traité, sans aucun exemple, vérification ou explication:
"Le code C est utile lorsque vous souhaitez avoir plusieurs liaisons de langue pour votre bibliothèque"
C'est une paraphrase. Je devrais noter que plusieurs personnes soulignent que plusieurs liaisons de langage sont possibles en C ++ (via certains extern
fonctionnements), mais néanmoins, si vous lisez ce post dans son intégralité, il est assez évident que C est idéal pour la liaison de portabilité / langage. Ma question est: pourquoi?
Quelqu'un peut-il fournir des raisons concrètes pour lesquelles écrire des bibliothèques en C facilite les liaisons et / ou la portabilité dans d'autres langues?
Réponses:
C a une interface beaucoup, beaucoup plus simple, et ses règles pour convertir une interface de code source en une interface binaire sont suffisamment simples pour que la génération d’interfaces externes auxquelles se lier se lie soit faite d’une manière bien établie. C ++, en revanche, a une interface incroyablement compliquée et les règles de liaison ABI ne sont pas du tout normalisées, ni formellement, ni dans la pratique. Cela signifie que quasiment n'importe quel compilateur, quel que soit le langage, quelle que soit la plate-forme, peut se lier à une interface C externe et savoir exactement à quoi s'attendre, mais pour une interface C ++, c'est essentiellement impossible car les règles changent en fonction du compilateur, de la version et de la version. plate-forme avec laquelle le code C ++ a été construit.
la source
extern "C"
il reste encore du travail supplémentaire à faire, elle doit être contrebalancée par les fonctionnalités fournies par C ++)extern "C"
.Si vous essayez de communiquer avec un locuteur d'une autre langue, le pidgin est plus facile que l'anglais shakespearien.
Les concepts de C - appels de fonction, pointeurs, chaînes terminées par NULL - sont très simples, de sorte que d'autres langages peuvent facilement les implémenter suffisamment pour appeler des fonctions C. Pour des raisons historiques, de nombreux autres langages sont implémentés en C, ce qui facilite encore davantage l’appel de fonctions C.
C ++ ajoute pas mal de choses - des classes, avec l'héritage, des vtables et des modificateurs d'accès; les exceptions, avec décompression de la pile et modification du flux de contrôle; modèles. Tout cela rend plus difficile l’utilisation des liaisons C ++ par d’autres langages: au mieux, il faut implémenter davantage de code "collant" ou interopérabilité, et au pire, les concepts ne sont pas traduits directement (en raison de différences dans les modèles de classe, la gestion des exceptions, etc.). Pour les modèles en particulier, leur simple utilisation (leur instanciation) nécessite généralement une étape de compilation avec un compilateur C ++, ce qui complique considérablement leur utilisation à partir d'autres environnements.
Cela dit, il est possible d'exagérer la difficulté de fournir des liaisons d'une bibliothèque C ++ vers un autre langage:
extern "C"
, de sorte que vous pouvez exporter des liaisons de langage de style C (avec toute la simplicité et la compatibilité des liaisons C) à partir d'une bibliothèque C ++ (avec la limitation que vous ne pouvez exposer aucune fonctionnalité spécifique à C ++) .la source
C est l’une des langues les plus anciennes qui existe encore. Son ABI est simple et pratiquement tous les systèmes d’exploitation encore utilisés aujourd’hui y ont été écrits . Certains de ces systèmes d’exploitation peuvent avoir ajouté des éléments, par exemple en C # / .NET ou autre, mais en-dessous, ils sont très imprégnés de C.
Cela signifie que, pour utiliser les fonctionnalités fournies par le système d'exploitation, pratiquement tous les langages de programmation existants avaient besoin d'un moyen d'interface avec les bibliothèques C de toute façon . Perl, Java, C ++, ils fournissent tous nativement des moyens de "parler C", car ils devaient le faire s'ils ne voulaient pas réinventer chaque roue.
Cela fait de C le latin des langages de programmation. (Combien d'années d'internet avant cette métaphore doit être "l'anglais des langues de progamming"?)
Lorsque vous écrivez votre bibliothèque en C, vous bénéficiez d’une interface gratuite (évidemment). Si vous écrivez votre bibliothèque en C ++, vous pouvez obtenir des liaisons en C, via des
extern "C"
déclarations comme vous l'avez mentionné.Cependant , vous pouvez obtenir ces liaisons que pour des fonctionnalités qui peuvent être exprimées en C .
Donc, votre API de bibliothèque ne peut pas utiliser ...
Un exemple simple, vous auriez besoin que vos fonctions exportées prennent et renvoient arrays (
[]
) à la place destd::vector
(oustd::string
d'ailleurs).Ainsi, non seulement vous ne seriez pas en mesure de fournir les avantages de C ++ aux clients de votre bibliothèque, mais vous devrez également déployer des efforts supplémentaires pour "traduire" votre API de bibliothèque de C ++ en "compatible C" (
extern "C"
).C’est pourquoi on pourrait faire valoir que C est le meilleur choix pour la mise en place d’une bibliothèque. Personnellement, je pense que les avantages du C ++ l'emportent toujours sur les efforts nécessaires pour une
extern "C"
API, mais ce n'est que moi.la source
En laissant de côté les détails déjà fournis par d'autres réponses:
La raison pour laquelle tant de langues fournissent une liaison C est que tous les systèmes d'exploitation Windows et * exposent la plupart de leurs API de système d'exploitation via une interface C. Donc, l'implémentation du langage doit déjà s'interfacer avec C pour pouvoir fonctionner sur les principaux Oses. Par conséquent, il est simple de proposer également une communication directe avec toute interface C à partir du langage lui-même.
la source
Il n'y a pas de raison. Si la sémantique que vous essayez d'exprimer est fondamentalement compatible avec le C et ne ressemble en rien à des modèles, il n'y a aucune raison de simplifier la liaison si l'implémentation est écrite en C. En fait, c'est à peu près par définition qu'une interface C peut être rempli par toute implémentation pouvant respecter le contrat binaire, y compris une implémentation dans une autre langue. Il existe des langages autres que C ++ pouvant implémenter des contrats binaires C pouvant fonctionner de cette manière.
Cela revient vraiment à des gens qui ne veulent pas apprendre de nouvelles langues ou des idées qui ont une sémantique ou des fonctionnalités utiles qui tentent désespérément de trouver une raison quelconque de rester à l’époque des dinosaures.
la source
L'interface avec une autre langue comporte deux axes principaux:
C a un avantage sur C ++ sur ces deux fronts:
Maintenant, pourquoi la plupart des langues ont-elles un ensemble de concepts similaire à celui de C? Cela peut être dû au fait qu'il est "simple" ou "préexistant". cela n'a pas d'importance cependant, le fait est qu'ils le font.
Au contraire, le C ++ a des concepts complexes et l’ABI est décidé par chaque compilateur (bien que beaucoup adhèrent à l’ABI d’Itanimum, sauf sous Windows ...). Herb Sutter a en fait proposé de faire en sorte que les systèmes d’exploitation corrigent une ABI C ++ (système par système d’exploitation) afin de résoudre partiellement ce problème. En outre, il convient de noter qu’un FFI C ++ est possible, D le tente 3 .
1 Sauf variadics (
...
), ce ne sont pas simples2 C a-t-il un ABI standard?
3 Interfaçage de D avec du code C ++ hérité
la source
Fondamentalement, il s’agit de la normalisation ABI. Bien que ni C, ni C ++ ne disposent d'une ABI normalisée que d'autres langages peuvent utiliser pour faire l'interface entre les binaires écrits, le C est devenu un standard de facto, tout le monde le sait et tout le monde peut utiliser les mêmes règles simples que le langage a pour types et appels de fonction.
C ++ pourrait avoir une ABI standard, mais Stroustrup a déclaré qu'il n'en voyait pas la nécessité. Il dit également qu'il serait difficile d'obtenir un consensus des rédacteurs de compilateurs (bien que je doute que le comité de standard C ++ émette une ABI similaire à celles existantes et que les rédacteurs de compilateurs modifient simplement la version suivante de leurs compilateurs, qui sont parfois incompatibles avec les fichiers binaires. de toute façon, construit avec d’anciennes versions de leurs compilateurs - je me souviens de la recompilation de quelques bibliothèques avec un nouveau compilateur Sun et de la conclusion qu’elles ne fonctionnaient pas avec les anciennes)
Vous remarquerez que certaines entreprises ont commencé à utiliser une ABI standard. Microsoft a démarré ce processus avec COM dans les années 90 et l'a aujourd'hui affiné dans ABI WinRT (à ne pas confondre avec l'autre WinRT qui fait référence à type de table) qui permet aux programmes écrits en C # de communiquer avec des bibliothèques écrites en C ou C ++ (c’est-à-dire que la couche de système d’exploitation propre à Microsoft est écrite en C ++, exposée à l’aide de WinRT et consommée par les applications C # lorsqu’elles appellent une routine d’exécution OS)
Personne ne peut faire grand chose à moins qu'un organisme de normalisation n'intervienne et ne corrige cette situation. Microsoft en voit évidemment la valeur et a pris des mesures pour la résoudre pour leur plate-forme.
Donc, la réponse est vraiment que C ne fournit pas de liens de langage. Il arrive que personne ne les ait écoutés et les consomme malgré tout.
la source
Toutes les réponses ne répondent pas au vrai problème: la compilation en C ++ introduit le "changement de nom", ainsi les fichiers binaires sont incompatibles avec les appels de fonctions "simples".
Tout ce que ABI contient n’est rien de plus qu’une tentative de standardisation.
En général, il n'est pas garanti que vous puissiez interconnecter des fonctions compilées avec différents compilateurs, même si vous vous en tenez à du C ++ standard. Autrefois, il était certain qu’ils étaient incompatibles, mais de nos jours, la normalisation fait son chemin;)
OTOH C a été conçu précisément pour être un "assemblage de haut niveau" et permettre toutes sortes d'interfaces faciles. Cela ne devrait pas surprendre que cela convienne mieux aux goûts multilingues.
Note latérale: le compilateur C ++ original (cfront) a en fait produit une source C qui devait être compilée, exactement comme gcc produisant Assembly "sous le capot".
la source