I file oggetto (C) creati con diversi compilatori sono compatibili con i binari?

11

Capisco che i compilatori C ++ non sono compatibili tra loro. Tuttavia, non sono stato in grado di trovare nulla su questo argomento per C in particolare. So che lo standard C lascia molto spazio ai compilatori per implementare le cose come meglio credono: ad esempio, la dimensione e l'allineamento della maggior parte dei tipi di dati (tutti?) È definito dall'implementazione, salvo alcune minime garanzie. Pertanto, due compilatori (o due versioni dello stesso compilatore) possono non essere d'accordo su numerosi dettagli.

Ho ragione nel ritenere che non ci sia alcuna garanzia che due file oggetto compilati con compilatori diversi si colleghino effettivamente? Ad esempio, la dimensione dei puntatori potrebbe essere 32 bit in un file oggetto e 64 bit nell'altro. Ma se è così, perché le librerie C a volte vengono distribuite in forma precompilata? C'è una previsione che userò lo stesso compilatore che hanno fatto (ad es. Gcc), o qualche standard de facto usato per assicurare la compatibilità binaria? E in che modo altre lingue con un'interfaccia in lingua straniera assicurano che le cose si allineeranno correttamente quando si collegano ai file oggetto C?

    
posta Doval 11.04.2014 - 19:44
fonte

2 risposte

10

La risposta generale è no, i compilatori di linguaggio C non sono compatibili tra loro. Lo standard di linguaggio C non definisce alcun tipo di interoperabilità binaria e la maggior parte degli scrittori di compilatori non ci provano nemmeno.

Ho bisogno di qualificarlo. Gli oggetti emessi da un compilatore C devono essere collegati con le librerie di runtime per produrre una libreria collegabile eseguibile o runtime. Sebbene le funzioni visibili fornite dalla libreria di runtime C dovrebbero essere compatibili, ci saranno anche funzioni non visibili che sono esclusive dell'implementazione e impediscono l'interoperabilità.

Questa mancanza di compatibilità si estende anche a diverse versioni dello stesso compilatore. In generale, i programmi e le librerie compilati con versioni precedenti e successive di un compilatore non possono essere collegati insieme e quelli compilati con MSVC non possono essere collegati a quelli compilati da GCC.

Esiste un'eccezione specifica e molto utile. Ogni piattaforma fornisce un collegamento dinamico ABI (Application Binary Interface) e qualsiasi programma in qualsiasi linguaggio che possa essere conforme all'ABI compatibile. Pertanto è generalmente possibile creare una DLL (su Windows) con MSVC (o qualcos'altro) e chiamarla da un programma compilato da una versione diversa di MSVC o GCC e viceversa.

Ci sono altri due ABI su Windows: gli assembly COM e .NET e si estendono su una vasta gamma di lingue. Quindi l'interoperabilità è sicuramente possibile, ma non è compatibile.

Il grado di incompatibilità può essere facilmente visto confrontando le mappe del linker. Per GNU usa ld -M , per MSVC usa link /map . Studia i due file generati. Entrambi avranno nomi che tu riconosci, come printf e main, sebbene (a seconda delle opzioni) i nomi possano essere storpiati in vari modi. Avranno anche nomi completamente diversi, molti dei quali non riconoscerete. Affinché i file oggetto prodotti da diversi compilatori siano compatibili devono concordare tutti questi nomi e non lo fanno mai. Neppure versioni diverse dello stesso compilatore possono sempre farlo.

    
risposta data 12.04.2014 - 13:35
fonte
16

Quello che stai cercando è chiamato ABI (Application Binary Interface).

Il linguaggio C non definisce un ABI, quindi in questo senso non c'è davvero alcuna garanzia che i file C compilati con diversi compilatori funzionino l'uno con l'altro.

D'altra parte, sulla maggior parte delle piattaforme il sistema operativo definisce un ABI per l'interfacciamento con esso e tutti i compilatori che prendono di mira quel sistema operativo & la famiglia di processori usa anche lo stesso ABI per interfacciarsi con componenti non OS. Quindi, in pratica, gli oggetti C creati da diversi compilatori possono funzionare l'uno con l'altro.

    
risposta data 11.04.2014 - 23:14
fonte

Leggi altre domande sui tag