10
votes

Le constructeur par défaut et le destructeur sont-ils toujours en ligne?

Je suis curieux si le constructeur par défaut et destructeurs que le compilateur génère des éléments en ligne ou non, car je peux justifier de toute partie. D'une part, vous voulez que le constructeur / destructeur par défaut pas soyez en ligne, de sorte que l'ajout plus tard ne casse pas abi (car les fichiers d'objet compilaient lorsque seules les valeurs par défaut auront été inlinées les définitions générées au lieu de ce que vous définissez). D'autre part, pour un compilateur C ++ pour compiler C Code C qui fonctionne ainsi que lorsqu'il est compilé avec un compilateur C, il ne peut pas ajouter d'appels de constructeur / destructeur pour chaque structure allouée et en C ++ la seule différence fonctionnelle entre une classe et une structure est censée être la protection d'accès par défaut. Peut-être que le lien traite-t-il d'une manière ou d'une autre? Peut-être que la réponse varie selon les compilateurs?

Une conséquence de cette question: Si j'ai une structure de pod en C ++, puis-je bénéficier théoriquement sous certains compilateurs en définissant le constructeur / destructeurs en ligne vide moi-même à la place des valeurs par défaut?


2 commentaires

La différence entre le Classe et struct Les mots-clés ne sont pas supposés.


@LUC: supposé en ce sens qu'il s'agit du type d'obscura où je pouvais voir un compilateur ne pas être conformes aux normes.


3 Réponses :


3
votes

Si j'ai une structure de pod en C ++, puis-je bénéficier théoriquement sous certains compilateurs en définissant le constructeur / destructeurs en ligne vide moi-même à la place des défauts?

théorotique, oui! Toute fonction (y compris les constructeurs et destructeurs) peut être déclarée en ligne et mettre le corps de la fonction dans la définition de la classe est une façon de le faire. Cependant, il dépend du compilateur s'il fait en réalité la fonction.


8 commentaires

Cela ne traite pas de ma question. Je demande si le constructeur / destructeur généré par défaut généré par le compilateur par défaut est en ligne.


@Joseph Garvin: Je crois que cela variera d'un compilateur au compilateur et de la façon dont cela affecte-t-il la façon dont vous avez écrit vos implémentations de toute façon?


@Als: J'ai édité ma question à inclure une façon dont cela pourrait compter en bas.


Hélas, selon la citation de la norme de Cubbi, on dirait que la vraie réponse est non. La norme les définit déjà comme inline.


@Joseph Garvin: Le point est que "sont en ligne" n'est pas vraiment significatif dans ce contexte. Le mot-clé inline appliqué à une fonction ne garantit pas que la fonction sera inlinée et l'absence du marquage inline (que ce soit explicitement en utilisant explicitement Le mot clé, ou implicitement), n'empêche pas la fonction d'être inlincé. Ce n'est qu'un indice.


@Karl: Généralement un bon point - + 1ed - mais je crois que ce n'est pas tout à fait correct ... Par exemple, une fonction hors ligne compilée dans une bibliothèque partagée ne peut pas être inlinée par code client à l'extérieur de cette bibliothèque partagée pendant la compilation ou La liaison, sinon la variation de la bibliothèque partagée ne varierait pas de manière fiable la mise en œuvre. Pour y garantir cela, l'inlinisation ne traverse normalement pas les limites de l'unité de traduction avant le temps de liaison, puis seuls les objets liés statiquement liés peuvent envisager une telle affranchie ... à partir d'une perspective d'outils - un temps douloureux de devoir le réaliser.


@Tony Oui, A +1 pour vous aussi - L'optimisation du temps de liaison n'est pas une chose facile, Afaik :)


@Karl: Depuis un point de vue ABI, cependant, que vous ne pouvez pas savoir ce que le compilateur fera des moyens, vous devez être conservateur et supposer qu'il a inlisé la fonction. C'est une raison pour laquelle il est bon de connaître la réponse à cette question.



19
votes

La norme C ++ dit, dans 12.1 [Class.ctor] / 5

Un constructeur par défaut déclaré implicitement est un membre du public en ligne de sa classe

et dans 12,4 [classe.dtor] / 3

une déclaration implicitement déclarée Destructeur est un membre public en ligne de sa classe.


2 commentaires

Ce que je prends pour signifier beaucoup la même chose que le mot clé inine - que le compilateur est libre d'exercer son propre jugement et besoin pas réellement en ligne le constructeur si c'est excessivement grand ... Est-ce votre compréhension aussi?


@Tony je le pense, oui. 7.1.2 / 2 dit, auto-référentiellement, "une implémentation n'est pas tenue d'exécuter cette substitution en ligne au point d'appel; toutefois, même si cette substitution en ligne est omise, les autres règles relatives aux fonctions en ligne définies par 7.1.2 doivent toujours être respecté "



2
votes

Il varie selon les compilateurs, mais en général: oui, ils devraient.

avec le GCC au moins, vous obtenez une fonction en ligne et une fonction hors ligne générée. La version hors ligne est marquée comme "lien une fois", donc quel que soit le nombre d'objets générant un constructeur par défaut, à la plupart une seule version se retrouvera dans la sortie liée. Si même personne n'utilise le constructeur par défaut hors ligne, il n'est pas inclus dans la sortie liée du tout et vous avez efficacement une fonction purement intégrée.


2 commentaires

Non, la norme les oblige à être inline.


@Gene, aucune norme ne nécessite qu'ils doivent être en ligne , ce qui n'est pas la même chose.