179 votes

Fonction statique en C

Quel est l'intérêt de rendre une fonction statique en C ?

220voto

pmg Points 52636

Le cacher aux autres unités de traduction : encapsulation.

fichier d'aide.c

int f1(int);        /* prototype */
static int f2(int); /* prototype */

int f1(int foo) {
    return f2(foo); /* ok, f2 is in the same translation unit */
                    /* (basically same .c file) as f1         */
}

int f2(int foo) {
    return 42 + foo;
}

main.c :

int f1(int); /* prototype */
int f2(int); /* prototype */

int main(void) {
    f1(10); /* ok, f1 is visible to the linker */
    f2(12); /* nope, f2 is not visible to the linker */
    return 0;
}

85voto

Stephen Canon Points 58003

pmg a raison en ce qui concerne l'encapsulation ; au-delà du fait de cacher la fonction aux autres unités de traduction (ou plutôt, parce que de celui-ci), en faisant des fonctions static peut également conférer des avantages en termes de performances en présence d'optimisations du compilateur.

Parce que static ne peuvent pas être appelées à partir de n'importe quel endroit en dehors de l'unité de traduction actuelle, le compilateur contrôle tous les points d'appel dans une fonction static fonction. Cela signifie qu'elle est libre d'utiliser une ABI non standard, d'être entièrement inline, ou d'effectuer un certain nombre d'autres optimisations qui ne seraient pas possibles pour une fonction avec un lien externe.

31voto

3Doubloons Points 1099

Le site static en C est utilisé dans un fichier compilé (.c par opposition à .h) afin que la fonction n'existe que dans ce fichier.

Normalement, lorsque vous créez une fonction, le compilateur génère des informations que l'éditeur de liens peut utiliser pour lier un appel de fonction à cette fonction. Si vous utilisez le mot-clé static, d'autres fonctions dans le même fichier peuvent appeler cette fonction (parce que cela peut être fait sans recourir à l'éditeur de liens), tandis que l'éditeur de liens n'a aucune information permettant à d'autres fichiers d'accéder à la fonction.

12voto

mercury0114 Points 417

En regardant les messages ci-dessus, je voudrais donner une réponse plus claire :

Supposons que notre main.c ressemble à ceci :

#include "header.h"

int main(void) {
    FunctionInHeader();
}

Considérons maintenant trois cas :

  • Cas 1 : Notre site header.h ressemble à ceci :

     #include <stdio.h>
    
     static void FunctionInHeader();
    
     void FunctionInHeader() {
         printf("Calling function inside header\n");
     }

    Puis la commande suivante sur linux :

     gcc main.c -o main

    réussira ! C'est parce qu'après le main.c inclut le fichier header.h la définition de la fonction statique sera dans la même main.c (plus précisément, dans la même unité de traduction) à l'endroit où il est appelé.

    Si l'on court ./main le résultat sera Calling function inside header ce qui est ce que cette fonction statique doit imprimer.

  • Cas 2 : Notre en-tête header.h ressemble à ça :

      static void FunctionInHeader();     

    et nous avons aussi un autre fichier header.c qui ressemble à ceci :

      #include <stdio.h>
      #include "header.h"
    
      void FunctionInHeader() {
          printf("Calling function inside header\n");
      }

    Puis la commande suivante

      gcc main.c header.c -o main

    donnera une erreur. Dans ce cas main.c ne comprend que la déclaration de la fonction statique, mais la définition est laissée dans une autre unité de traduction et l'élément static Le mot-clé empêche le code définissant une fonction d'être lié.

  • Cas 3 :

    Similaire au cas 2, sauf que maintenant notre en-tête header.h est :

      void FunctionInHeader(); // keyword static removed

    Ensuite, la même commande que dans le cas 2 réussira, et l'exécution suivante ./main donnera le résultat escompté. Ici, le FunctionInHeader se trouve dans une autre unité de traduction, mais le code qui la définit peut être lié.

Ainsi, pour conclure :

static keyword prevents the code defining a function to be linked,
when that function is defined in another translation unit than where it is called.

5voto

Les programmeurs C utilisent l'attribut static pour cacher les déclarations de variables et de fonctions dans les modules, tout comme vous utiliseriez les déclarations public et private en Java et C++. Les fichiers source C jouent le rôle de modules. Toute variable ou fonction globale déclarée avec l'attribut static est privée à ce module. De même, toute variable ou fonction globale déclarée sans l'attribut static est publique et accessible à tout autre module. accessible à tout autre module. Une bonne pratique de programmation consiste à protéger vos variables et vos fonctions avec l'attribut static dans la mesure du possible.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X