482 votes

Comment fonctionne la compilation, processus de mise en relation de travail?

J'ai été à la programmation en C++ depuis un moment et je me demandais comment le compilateur et le processus de liaison fonctionne réellement?

Quelqu'un peut m'expliquer s'il vous plaît?

(Note: Ceci est destiné à être une entrée à Débordement de Pile du C++ FAQ. Si vous voulez une critique de l'idée de fournir une FAQ dans ce formulaire, puis de la poster sur meta qui a commencé tout cela serait l'endroit pour le faire. Les réponses à cette question sont surveillés en C++ salon, où la FAQ idée a commencé à en premier lieu, de sorte que votre réponse est très probablement le faire lire par ceux qui sont venus avec l'idée.)

640voto

R. Martinho Fernandes Points 96873

La compilation d'un programme C++ comporte plusieurs étapes:

  1. Prétraitement: le préprocesseur prend un code source C++ de fichier et traite de l' #includes, #defines et d'autres directives de préprocesseur. La sortie de cette étape est un "pur" fichier C++ sans pré-processeur directives;

  2. Compilation: le compilateur prend le pré-processeur de sortie et produit un fichier objet.

  3. Liens: l'éditeur de liens prend des fichiers de l'objet produit par le compilateur et génère une bibliothèque ou d'un fichier exécutable.

Prétraitement

Le préprocesseur gère les directives de préprocesseur, comme #include et #define. Il est agnostique de la syntaxe de C++, qui est pourquoi il doit être utilisé avec précaution.

Il travaille sur un fichier source C++ à un moment par le remplacement, #include directives avec le contenu des différents fichiers (c'est en général des déclarations), de faire le remplacement de macros (#define), et en sélectionnant les différentes portions de texte en fonction de l' #if, #ifdef et #ifndef directives.

Le préprocesseur est de travailler sur un flux de prétraitement, jeton, et la substitution macro est définie comme le fait de remplacer les jetons par d'autres jetons (l'opérateur ## permet de fusionner deux jetons lorsqu'il sens).

Après tout ce qu'il produit une sortie unique qui est un flux de jetons résultant des transformations décrites ci-dessus. Il ajoute également un des marqueurs qui indiquent au compilateur où chaque ligne est venu de sorte qu'il peut utiliser ceux de créer des messages d'erreur.

Certaines erreurs peuvent être produites à ce stade grâce à une utilisation intelligente de l' #if et #error directives.

Compilation

L'étape de compilation est effectuée sur chaque sortie du préprocesseur. Elle implique l'analyse du code source C++ (maintenant, sans les directives de préprocesseur) et, de produire un fichier objet. Ce fichier contient le code compilé (sous forme binaire) des symboles définis dans l'entrée. Symboles dans des fichiers objets sont désignés par le nom.

Les fichiers objets peut se référer à des symboles qui ne sont pas définis. C'est le cas lorsque vous utilisez une déclaration, et ne fournissent pas de définition. Le compilateur n'a pas l'esprit ce, et sera heureux de produire le fichier d'objet tant que le code source est bien formé.

Les compilateurs vont arrêter la compilation à ce point. Ceci est très utile car avec elle, vous pouvez compiler chaque fichier de code source séparément. L'avantage de cette offre est que vous n'avez pas besoin de recompiler le tout si vous modifiez uniquement un seul fichier.

Le produit objet de fichiers peuvent être mis dans des archives spéciales appelées bibliothèques statiques, pour faciliter la réutiliser plus tard.

C'est à ce stade de la "régulière" des erreurs du compilateur, comme des erreurs de syntaxe ou de l'échec de la résolution de surcharge des erreurs sont signalées.

La liaison

L'éditeur de liens est ce qui produit la compilation finale de sortie à partir des fichiers de l'objet, le compilateur produit. Cette sortie peut être soit partagé (ou dynamique) de la bibliothèque (et alors que le nom est similaire, ils n'ont pas beaucoup en commun avec les bibliothèques statiques mentionné plus haut) ou d'un fichier exécutable.

Il relie tous les fichiers de l'objet en remplaçant les références aux symboles non définis contenue dans ceux-ci avec les bonnes adresses. Chacun de ces symboles peuvent être définis dans d'autres fichiers de l'objet ou dans des bibliothèques. Si elles sont définies dans les bibliothèques autres que la bibliothèque standard, vous devez dire à l'éditeur de liens à leur sujet.

À ce stade, les erreurs les plus courantes sont le manque de définitions ou de dupliquer des définitions. L'ancien signifie que les définitions n'existent pas (c'est à dire qu'ils ne sont pas écrites), ou que l'objet des fichiers ou des bibliothèques où ils résident n'ont pas été donnés à l'éditeur de liens. Ce dernier est évidente: le même symbole a été défini dans deux différents fichiers objets ou des bibliothèques.

56voto

user2003323 Points 1

La compilation n'est pas tout à fait la même que la création d'un fichier exécutable! Au lieu de cela, créer un fichier exécutable est un processus en plusieurs étapes divisé en deux composantes: la compilation et la liaison. En réalité, même si un programme compile bien" il ne pourrait pas en fait de travail en raison d'erreurs lors de la liaison de la phase. Le processus total de passe de fichiers de code source pour un fichier exécutable peut-être mieux d'être considérée comme une construction.

Compilation

La Compilation se réfère à la transformation de fichiers de code source (.c, .cc, ou .rpc) et la création d'un "objet" de fichier. Cette étape ne crée rien, l'utilisateur peut exécuter. Au lieu de cela, le compilateur simplement produit les instructions en langage machine qui correspondent le fichier de code source qui a été compilé. Par exemple, si vous compilez (mais ne pas le lien) trois fichiers distincts, vous avez trois fichiers objets créés en tant que sortie, chacune avec le nom .o ou .obj (l'extension dépendra de votre compilateur). Chacun de ces fichiers contient une traduction de votre fichier de code source en langage machine de fichier, mais vous ne pouvez pas exécuter (encore)! Vous avez besoin de les transformer en fichiers exécutables de votre système d'exploitation peut utiliser. C'est là que l'éditeur de liens.

La liaison

La liaison se réfère à la création d'un seul fichier exécutable à partir de plusieurs fichiers de l'objet. Dans cette étape, il est fréquent que l'éditeur de liens se plaindre de fonctions non définies (généralement, le principal lui-même). Lors de la compilation, si le compilateur n'a pas pu trouver la définition d'une fonction particulière, il suffit de supposer que la fonction a été définie dans un autre fichier. Si ce n'est pas le cas, il n'y a pas de chemin le compilateur savez, il ne faut pas regarder le contenu de plus d'un fichier à la fois. L'éditeur de liens, d'autre part, peut regarder plusieurs fichiers et essayer de trouver des références pour les fonctions qui n'ont pas été mentionnés.

Vous pourriez vous demander pourquoi il y a compilation séparée et pas de liaison. Tout d'abord, il est probablement plus facile à mettre en œuvre les choses de cette façon. Le compilateur ne sa chose, et l'éditeur de liens ne son truc, en gardant les fonctions de séparation, la complexité du programme est réduite. L'autre (le plus évident) l'avantage est que cela permet la création de grands programmes sans avoir à refaire l'étape de la compilation à chaque fois qu'un fichier est modifié. Au lieu de cela, à l'aide de soi-disant "compilation conditionnelle", il est nécessaire de compiler uniquement les fichiers source qui ont changé; pour le reste, les fichiers objets sont-ils suffisamment d'informations pour l'éditeur de liens. Enfin, il est simple à mettre en œuvre les bibliothèques de pré-compilé le code: il suffit de créer des fichiers d'objets et de les relier comme tout autre objet fichier. (Le fait que chaque fichier est compilé séparément à partir des informations contenues dans d'autres fichiers, d'ailleurs, est appelé le "séparer le modèle de compilation".)

Pour obtenir tous les avantages de la condition de la compilation, il est probablement plus facile d'obtenir un programme pour vous aider à faire qu'à essayer et n'oubliez pas les fichiers que vous avez modifiés depuis la dernière compilation. (Vous pouvez, bien sûr, il suffit de recompiler tous les fichiers qui ont un horodatage de plus que le timestamp de l'objet correspondant de fichier.) Si vous travaillez avec un environnement de développement intégré (IDE), il peut déjà prendre soin de cela pour vous. Si vous êtes en utilisant des outils en ligne de commande, il y a une chouette utilitaire appelé faire qui vient avec la plupart des *nix distributions. Avec la compilation conditionnelle, il a plusieurs autres fonctionnalités intéressantes pour la programmation, comme permettre à différentes compilations de votre programme (par exemple, si vous avez une version de produire des résultats détaillés pour le débogage.

Connaître la différence entre la phase de compilation et de la phase de liaison peut rendre plus facile la chasse aux bugs. Les erreurs de compilation sont généralement syntaxique de la nature-un point-virgule manquant, une parenthèse supplémentaires. Les erreurs de liaison ont généralement à voir avec manquant ou plusieurs définitions. Si vous obtenez une erreur qu'une fonction ou une variable est défini plusieurs fois à partir de l'éditeur de liens, c'est une bonne indication que l'erreur est que deux de vos fichiers de code source ont la même fonction ou une variable.

25voto

AProgrammer Points 31212

Sur la façade standard:

  • une unité de traduction est la combinaison d'une source de fichiers, inclus les en-têtes et les fichiers sources moins les lignes de source ignorée par conditionnelle inclusion directive de préprocesseur.

  • la norme définit les 9 phases de la traduction. Les quatre premiers correspondent à prétraitement, les trois sont de la compilation, le suivant est l'instanciation de modèles (la production de l'instanciation d'unités) et la dernière est la liaison.

Dans la pratique, la huitième phase (l'instanciation de modèles) est souvent faite pendant le processus de compilation, mais certains compilateurs retarder le lien entre la phase et certains se propager dans les deux.

22voto

Eliptical view Points 421

Le skinny est qu'un CPU charge les données à partir d'adresses de mémoire stocke des données d'adresses de la mémoire, et d'exécuter des instructions séquentiellement de la mémoire d'adresses, avec quelques sauts conditionnels dans la séquence d'instructions traitées. Chacune de ces trois catégories d'instructions comporte le calcul d'une adresse à une cellule de mémoire à être utilisé dans la machine de l'instruction. Parce que la machine des instructions sont de longueur variable selon les instructions impliqués, et parce que nous avons une chaîne de longueur variable de l'ensemble que nous construisons notre code machine, il y a un processus en deux étapes impliquées dans le calcul et la construction de toutes les adresses.

Nous avons d'abord fixant les modalités de l'allocation de la mémoire du mieux que nous pouvons avant que nous puissions savoir ce qui se passe exactement dans chaque cellule. - Nous comprendre les octets ou de mots, ou de tout ce qui forme les instructions et les littéraux et toutes les données. Nous venons de commencer à allouer de la mémoire et de la construction de l'valeurs qui permettra de créer le programme que nous allons, et la note en bas de n'importe où nous avons besoin de revenir en arrière et corriger une adresse. Dans ce lieu, nous avons mis un mannequin à juste pavé de l'emplacement, de sorte que nous puissions continuer à calculer la taille de la mémoire. Pour exemple, notre premier code machine peut prendre l'une des cellules. Le prochain code machine peut prendre 3 cellules, comprenant un code machine de la cellule et deux adresse cellules. Maintenant, notre pointeur d'adresse est 4. Nous savons ce qui se passe dans la machine de la cellule, qui est l'op de code, mais nous devons attendre pour calculer ce qui se passe dans l'adresse des cellules jusqu'à ce que nous savons où ces données sera situé, c'est à dire ce qui va être la machine de l'adresse de ces données.

Si il y avait juste un fichier source d'un compilateur pourrait théoriquement produire entièrement exécutable du code machine sans un éditeur de liens. En deux passes processus, il pourrait calculer toutes les adresses de toutes les cellules de données référencée par une charge de la machine ou de stocker des instructions. Et elle pourrait calculer toutes les adresses absolues référencés par aucune absolue des instructions de saut. C'est de cette façon plus simple, les compilateurs, comme celui dans la Suite du travail, sans linker.

Un éditeur de liens est quelque chose qui permet de définir les blocs de code pour être compilés séparément. Cela peut accélérer le processus global de code du bâtiment, et permet une certaine souplesse avec la façon dont les blocs sont utilisées plus tard, en d'autres termes, ils peuvent être déplacés dans la mémoire, par exemple l'ajout de 1000 à chaque adresse scoot le bloc par 1000 adresses des cellules.

Donc, ce que le compilateur sorties est rugueuse du code machine qui n'est pas encore totalement construit, mais il est aménagé de façon à connaître la taille de tout ce qui, en d'autres mots, de sorte que nous pouvons commencer à calculer où toutes les adresses absolues sera situé. le compilateur génère également une liste de symboles qui sont le nom, l'adresse paires. Les symboles se rapportent à un offset de mémoire dans le code machine dans le module avec un nom. Le décalage étant la distance absolue par rapport à l'emplacement de la mémoire du symbole dans le module.

C'est là que nous arrivons à l'éditeur de liens. L'éditeur de liens de la première gifle l'ensemble de ces blocs de code machine, ensemble la fin de la fin et des notes où chacun commence. Il calcule ensuite les adresses pour être fixé par l'addition de l'offset relatif à l'intérieur d'un module et de la position absolue du module, dans le plus grand modèle.

Évidemment, j'ai simplifié à l'extrême de ce que vous pouvez essayer de le saisir, et je n'ai volontairement pas utilisé le jargon des fichiers objets, des tables de symboles, etc. ce qui pour moi est une partie de la confusion.

9voto

Charles Wang Points 14

Regardez l'URL: http://faculty.cs.niu.edu/~mcmahon/CS241/Notes/compile.html
Le complet compling processus de C++ est présenté clairement dans cette URL.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X