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.
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 ...
Puisque la question concerne C (pas C++), inline
signifie que
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.
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.