web-dev-qa-db-fra.com

petites fonctions définies dans les fichiers d'en-tête: en ligne ou statique?

J'ai un certain nombre de petites fonctions qui sont définies dans un fichier .h. C'est un petit projet (maintenant) et je veux éviter la douleur d'avoir des déclarations et des définitions séparées, car elles changent tout le temps. Pour éviter les symboles à définitions multiples, je peux les avoir soit static ou inline. Que faut-il préférer et pourquoi?

Je sais que c'est généralement une mauvaise pratique de définir des fonctions dans les en-têtes. Vous n'avez pas à mentionner que dans les réponses, cette question est techniquement posée.

20
eudoxos

J'utiliserais static inline, mais static fonctionnerait aussi bien.

extern et extern inline ont disparu car vous obtiendriez plusieurs définitions externes si l'en-tête est inclus dans plusieurs unités de traduction, vous devez donc prendre en compte les spécifications static, static inline et inline.

Heptic indique correctement dans sa réponse que la plupart des compilateurs considèrent les fonctions d’inline, que inline soit spécifié ou non, c’est-à-dire que le principal impact de inline est son effet sur le couplage.

Cependant, les définitions static ont un lien interne, il n'y a donc pas beaucoup de différence entre static et static inline; Je préfère static inline pour les définitions de fonction dans les fichiers d'en-tête pour des raisons purement stylistiques (règle générale: les fichiers d'en-tête ne doivent contenir que des déclarations extern, des définitions de variable static const et des définitions de fonction static inline).

inline sans static ou extern donne une définition inline, que la norme énonce (C99 6.7.4, §6)

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 function utilise la définition inline ou la définition externe.

c'est-à-dire que les définitions en ligne doivent toujours être accompagnées de définitions externes, ce qui n'est pas ce que vous recherchez.

Vous trouverez plus d'informations sur les subtilités de la sémantique en ligne C99 dans cette réponse , sur la page d'accueil Clang et le C99 Rationale (PDF) .

Gardez à l'esprit que GCC utilisera la sémantique C99 uniquement si -std=c99 ou -std=gnu99 est présent ...

25
Christoph

Puisque la question concerne C (pas C++), inline signifie que

  1. Vous souhaitez "que les appels à la fonction soient aussi rapides que possible" (ISO9899-1999, 6.7.4 (5)). Le même paragraphe indique également qu'il est défini par la mise en œuvre dans quelle mesure cette suggestion est efficace. En d’autres termes, elle a peu d’impact et n’implique aucune inline (en fait, la non-inline peut très probablement être plus rapide en raison des effets de cache d’instruction).
  2. il existe des restrictions et des cas spéciaux associés à extern (ISO9899-1999, 6.7.4 (6), par exemple, une fonction inline avec une liaison externe doit être définie dans la même unité de compilation, et une définition de inline permet à extern définition ailleurs sans erreur (ce qui n'est pas nécessairement une bonne chose, car les deux fonctions ne doivent pas nécessairement être équivalentes du point de vue fonctionnel, et le compilateur ne l'utilise pas à tout moment!). 

Les implications de l'éditeur de liens données par Heptic sont requises pour C++, mais pas par C (pour autant que je sache). Ils sont obligatoirement requis par le "doit avoir la même adresse dans toutes les unités de traduction" dans ISO14882, 7.1.2 (4). Je ne suis au courant d'aucune clause similaire dans le C99.
Cependant, étant donné que les langages entièrement différents, C et C++, utilisent généralement le même compilateur et éditeur de liens C/C++, il est probable que cela fonctionne de manière identique pour C, de toute façon.

Alors ... comment répondre à votre question? Utilisez inline lorsque vous estimez que c'est suffisant. Soyez conscient des pièges possibles de extern. Sinon, laissez-le de côté et faites confiance au compilateur pour le faire correctement.

3
Damon

Je pense que statique en ligne est le chemin à parcourir pour les fonctions que vous souhaitez intégrer, et seulement statique pour celles que vous ne voulez pas. 

static fait référence à la visibilité, mais inline est ambigu quant à la visibilité dans la norme (C99). Quoi qu’il en soit, ce n’est pas son objectif: inline est destiné aux fonctions d’alignement, il a donc un effet secondaire du point de vue de la visibilité que vous pourriez ne pas vouloir.

0
m0skit0