Que se passe-t-il avec une fonction inline externe?

Que se passe-t-il si je définis ma fonction dans mon fichier .h par

extern int returnaint(void); 

, définissez-le dans le fichier .c associé en tant que

 inline int returnaint(void) { return 1; } 

et inclure l’en-tête dans un autre fichier .c et utiliser la fonction? Lorsque je comstack les éléments séparément, en créant un fichier object pour chaque fichier .c, puis en les liant, la fonction en ligne est-elle incluse ou que se passe-t-il?

Je sais que le compilateur peut ignorer inline , mais que se passe-t-il s’il ne l’ignore pas dans ce cas?

Avoir ajouté le inline à la définition de la fonction dans le fichier .c est tout simplement superflu.

  • Votre unité de compilation du fichier .c voit une déclaration extern (sans inline ) et une définition inline . Ainsi, il émet le symbole de la fonction dans le fichier object.

  • Toutes les autres unités de compilation ne voient qu’une déclaration extern et peuvent donc utiliser la fonction sans problème si vous liez votre exécutable final à l’autre fichier .o .

En fait, vous l’avez juste dans le mauvais sens. Cette fonctionnalité est censée être utilisée pour que vous ayez la définition intégrée dans le fichier .h , visible par tout le monde. Cette définition de la fonction n’agit que comme une déclaration du symbole, comme le ferait extern , mais ne le définit pas.

Une déclaration extern dans un seul fichier .c (unité de compilation) garantit alors que le symbole est défini.

La terminologie est un peu déroutante, la définition inline agissant en tant que déclaration du symbole et la déclaration extern agissant en tant que définition.

Ça ne comstackra pas. C11 (ISO / IEC 9899: 2011) § 6.7.4 Spécificateurs de fonction (caractères gras ajoutés):

Toute fonction avec une liaison interne peut être une fonction en ligne. Pour une fonction avec liaison externe, les ressortingctions suivantes s’appliquent: Si une fonction est déclarée avec un spécificateur de fonction inline, elle doit également être définie dans la même unité de traduction. Si toutes les déclarations d’étendue de fichier pour une fonction dans une unité de traduction incluent le spécificateur de fonction en ligne sans extern, la définition dans cette unité de traduction est une définition en ligne. Une définition en ligne ne fournit pas de définition externe pour la fonction et n’interdit pas une définition externe dans une autre unité de traduction. Une définition en ligne fournit une alternative à une définition externe, qu’un traducteur peut utiliser pour implémenter tout appel à la fonction dans la même unité de traduction. Il n’est pas spécifié si un appel à la fonction utilise la définition en ligne ou la définition externe. 140)

140) Etant donné qu’une définition en ligne est distincte de la définition externe correspondante et de toute autre définition en ligne correspondante dans d’autres unités de traduction, tous les objects correspondants ayant une durée de stockage statique sont également distincts dans chacune des définitions.

L’autre fichier .c obtient uniquement la déclaration de la fonction inline partir de l’en-tête, mais pas la définition, ce qui est contraire à la règle en caractères gras.

MODIFIER:

Comme @Jens Gustedt le fait remarquer, mon explication précédente est fausse, car dans la question du PO, la fonction est déclarée comme non-inline dans le fichier d’en-tête:

 extern int returnaint(void); 

Donc, l’autre fichier .c le traitera comme une fonction normale.

Nous venons tout juste d’avoir un problème similaire et le fait de restr en ligne uniquement dans le fichier .c a résolu le problème avec des avertissements. L’accélération s’est également produite dans les deux fichiers avec et sans la définition de fonction. Compilation avec le drapeau -o3.