Règles de redéfinition de fonction inline statique C

Supposons que dans bar.h il pourrait exister:

 static inline int fun () { return 2; } 

Et pour que le fun soit toujours défini, foo.h contient les éléments suivants:

 static inline int fun () { return 3; } 

Est-ce que le comportement suivant bar.h indéfini lorsque bar.h contient la définition?

 #include "foo.h" /* ensure there is always a definition */ #include "bar.h" /* use the bar definition if it exists */ int main () { /* ... */ int x = fun (); /* ... */ 

Avec gcc (4.0.1) (ancien, mais c’est ce que j’ai actuellement), le comportement est celui attendu: la version foo est utilisée lorsque la version barre est manquante et la version barre est utilisée lorsqu’elle existe.

    Non, ce n’est pas autorisé. Ces définitions de fun() déclarent que fun() doit avoir un lien interne (en raison de la static ), et le §6.9 de la norme C dit:

    Il ne doit pas y avoir plus d’une définition externe pour chaque identificateur déclaré avec liaison interne dans une unité de traduction.

    La violation d’une clause “shall” constitue un comportement indéfini, ce qui signifie que la sémantique de votre programme est complètement indéfinie et que le compilateur n’a pas à émettre de message d’erreur.

    Vous n’êtes pas autorisé à faire cela, et votre compilateur ne devrait pas vous laisser faire.

    Vous pouvez avoir plusieurs définitions d’une fonction en ligne non statique uniquement si toutes les définitions sont identiques (mais jamais plus d’une définition par TU). Cela se produira nécessairement pour les fonctions en ligne définies dans les fichiers d’en-tête.

    Pour une liaison statique, chaque UT peut avoir une définition différente, mais vous ne pouvez toujours avoir qu’une définition par UT.

    (Désolé pour les modifications multiples.)

    Si vous voulez obtenir le même effet, vous pouvez utiliser une macro inoffensive:

     // foo.h - include guards omitted because of iPhone #ifndef VALUE # define VALUE 2 #endif static inline int fun() { return VALUE; } // bar.h #define VALUE 3 #include "foo.h" 

    Inclure les retournements de commande, mais c’est moins effrayant que la version complète de la macro (ce qui ne fait pas peur du tout à mon humble avis, mais je ne connais pas vos relations avec les macros de votre lieu de travail.)