Quel est l'intérêt de rendre une fonction statique en C ?
Réponses
Trop de publicités?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;
}
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.
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.
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 fichierheader.h
la définition de la fonction statique sera dans la mêmemain.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 seraCalling 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émentstatic
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, leFunctionInHeader
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.
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.
- Réponses précédentes
- Plus de réponses