Je comprends que les compilateurs C ++ ne sont pas compatibles entre eux. Cependant, je n'ai rien trouvé sur ce sujet pour C en particulier. Je sais que la norme C laisse beaucoup de place aux compilateurs pour implémenter les choses comme bon leur semble: par exemple, la taille et l'alignement de la plupart (tous?) Des types de données sont définis par l'implémentation, à l'exception de quelques garanties minimales. Par conséquent, deux compilateurs (ou deux versions du même compilateur) peuvent être en désaccord sur de nombreux détails.
Ai-je raison de penser qu'il n'y a aucune garantie que deux fichiers objets compilés avec des compilateurs différents seront effectivement liés correctement? Par exemple, la taille des pointeurs peut être de 32 bits dans un fichier objet et de 64 bits dans l'autre. Mais si c'est le cas, pourquoi les bibliothèques C sont-elles parfois distribuées sous forme précompilée? Y a-t-il une attente que j'utiliserai le même compilateur qu'eux (par exemple gcc), ou une norme de facto utilisée pour assurer la compatibilité binaire? Et comment les autres langues avec une interface en langue étrangère garantissent-elles que les choses s'aligneront correctement lors de la liaison avec les fichiers d'objets C?
Réponses:
La réponse générale est non, les compilateurs en langage C ne sont pas compatibles entre eux. Le standard du langage C ne définit aucun type d'interopérabilité binaire, et la plupart des rédacteurs de compilateurs n'essaient même pas.
Je dois qualifier cela. Les objets émis par un compilateur C doivent être liés aux bibliothèques d'exécution pour produire soit une bibliothèque exécutable soit une bibliothèque exécutable. Bien que les fonctions visibles fournies par la bibliothèque d'exécution C doivent être compatibles, il y aura également des fonctions non visibles qui sont uniques à l'implémentation et empêchent l'interopérabilité.
Ce manque de compatibilité s'étend également aux différentes versions du même compilateur. En général, les programmes et bibliothèques compilés avec des versions plus anciennes et plus récentes d'un compilateur ne peuvent pas être liés ensemble, et ceux compilés avec MSVC ne peuvent pas être liés avec ceux compilés par GCC.
Il existe une exception spécifique et très utile. Chaque plate-forme fournit une liaison dynamique ABI (Application Binary Interface) et tout programme dans n'importe quel langage qui peut se conformer à cette ABI est compatible. Par conséquent, il est généralement possible de créer une DLL (sous Windows) avec MSVC (ou autre chose) et de l'appeler à partir d'un programme compilé par une version différente de MSVC ou par GCC et vice versa.
Il existe deux autres ABI sur Windows: les assemblys COM et .NET, et ils couvrent un large éventail de langues. L'interopérabilité est donc certainement possible, mais compatible, elle ne l'est pas.
Le degré d'incompatibilité peut facilement être vu en comparant les cartes de l'éditeur de liens. Pour une utilisation GNU
ld -M
, pour une utilisation MSVClink /map
. Étudiez les deux fichiers générés. Les deux auront des noms que vous reconnaissez, tels que printf et main, bien que (selon les options) les noms soient susceptibles d'être modifiés de diverses manières. Ils auront également des noms complètement différents, dont beaucoup ne seront pas reconnus. Pour que les fichiers objets produits par différents compilateurs soient compatibles, ils doivent s'accorder sur tous ces noms, et ils ne le font jamais. Même les différentes versions du même compilateur ne peuvent pas toujours le faire.la source
Ce que vous recherchez s'appelle ABI (Application Binary Interface).
Le langage C ne définit pas d'ABI, donc dans ce sens il n'y a en effet aucune garantie que les fichiers C compilés avec différents compilateurs fonctionneront les uns avec les autres.
D'un autre côté, sur la plupart des plates-formes, le système d'exploitation définit un ABI pour l'interfaçage avec lui et tous les compilateurs ciblant ce système d'exploitation et cette famille de processeurs utilisent également ce même ABI pour l'interfaçage avec des composants non-OS. Ainsi, dans la pratique, les objets C créés par différents compilateurs peuvent fonctionner ensemble.
la source