web-dev-qa-db-fra.com

Pourquoi et quand utiliser des structures statiques en programmation C?

J'ai vu assez souvent des déclarations de structure statique dans un code de pilote qu'on m'a demandé de modifier.

J'ai essayé de chercher des informations sur les raisons pour lesquelles structs sont déclarées statiques et la motivation de le faire.

Quelqu'un parmi vous peut-il m'aider à comprendre cela?

37
kutty

Le mot clé static en C a plusieurs effets, selon le contexte auquel il est appliqué.

  • lorsqu'elle est appliquée à une variable déclarée à l'intérieur d'une fonction, la valeur de cette variable sera préservée entre les appels de fonction.
  • lorsqu'elle est appliquée à une variable déclarée en dehors d'une fonction, ou à une fonction, la visibilité de cette variable ou fonction est limitée à "unité de traduction" dans laquelle elle est déclarée - c'est-à-dire le fichier lui-même. Pour les variables, cela se résume à une sorte de "variable globale visible localement".

Les deux utilisations sont assez courantes dans le code de bas niveau comme les pilotes.

Les premiers, et les seconds lorsqu'ils sont appliqués aux variables, permettent aux fonctions de conserver une notion d'état entre les appels, ce qui peut être très utile, mais cela peut également causer toutes sortes de problèmes désagréables lorsque le code est utilisé dans n'importe quel contexte où il se trouve. être utilisé simultanément, soit par plusieurs threads ou par plusieurs appelants. Si vous ne pouvez pas garantir que le code sera strictement appelé en séquence par un "utilisateur", vous pouvez passer une sorte de structure "contextuelle" qui est maintenue par l'appelant à chaque appel.

Ce dernier, appliqué aux fonctions, permet à un programmeur de rendre la fonction invisible de l'extérieur du module, et il [~ # ~] peut [~ # ~] être un peu plus rapide avec certains compilateurs pour certaines architectures car le compilateur sait qu'il n'a pas à rendre la variable/fonction disponible en dehors du module - permettant par exemple la fonction d'être alignée.

32
fvu

Quelque chose que toutes les autres réponses semblent manquer: static est et spécifie également un durée de stockage pour un objet, ainsi que automatique (variables locales) et - alloué (mémoire retournée par malloc et ses amis).

Les objets avec une durée de stockage statique sont initialisés avant le démarrage de main (), soit avec l'initialiseur spécifié, soit, si aucun n'a été donné, comme si 0 lui avait été attribué (pour les structures et les tableaux, cela vaut pour chaque membre et de manière récursive).

La deuxième propriété static définie pour un identifiant, est son linkage, qui est un concept utilisé au moment du lien et indique à l'éditeur de liens quels identifiants font référence au même objet. Le mot clé static fait qu'un identifiant a lien interne, ce qui signifie qu'il ne peut pas faire référence à des identifiants du même nom dans une autre unité de traduction.

Et pour être pédant sur toutes les réponses bâclées que j'ai lues auparavant: une variable statique ne peut pas être référencée partout dans le fichier où elle est déclarée. Sa portée est seulement de sa déclaration (qui peut être entre les définitions de fonctions) jusqu'à la fin du fichier source - ou même plus petite, jusqu'à la fin du bloc englobant.

30
Jens

struct variable

Pour une struct variable comme static struct S s;, ceci a été largement discuté à: Que signifie "statique" en C?

struct définition: aucun effet :

static struct S { int i; int j; };

est exactement le même que:

struct S { int i; int j; };

alors ne l'utilisez jamais. GCC 4.8 émet un avertissement si vous le faites.

Cela est dû au fait que les définitions de structure n'ont pas de stockage et ne génèrent pas de symboles dans les fichiers objets comme les variables et les fonctions. Essayez simplement de compiler et de décompiler:

struct S { int i; int j; };
int i;

avec:

gcc -c main.c
nm main.o

et vous verrez qu'il n'y a pas de symbole S, mais il y a un symbole i.

Le compilateur utilise simplement des définitions pour calculer le décalage des champs au moment de la compilation.

C'est que les définitions de structure sont généralement incluses dans les en-têtes: elles ne généreront pas plusieurs données distinctes, même si elles sont incluses plusieurs fois.

Il en va de même pour enum.

C++ struct definition: obsolète en C++ 11

projet standard C++ 11 N3337 Annexe C 7.1.1:

Modification: en C++, les spécificateurs statiques ou externes ne peuvent être appliqués qu'aux noms d'objets ou de fonctions. L'utilisation de ces spécificateurs avec des déclarations de type est illégale en C++. En C, ces spécificateurs sont ignorés lorsqu'ils sont utilisés sur les déclarations de type.

Voir aussi: https://stackoverflow.com/a/31201984/895245

Si vous déclarez une variable comme étant static, elle n'est visible que dans cette nité de traduction (si elle est déclarée globalement) ou conserve sa valeur d'appel à appel (si déclarée à l'intérieur d'une fonction).

Dans votre cas, je suppose que c'est le premier cas. Dans ce cas, le programmeur ne voulait probablement pas que la structure soit visible à partir d'autres fichiers.

8
Mihai Maruseac

Le modificateur static pour le struct limite l'étendue de la visibilité de la structure à l'unité de traduction actuelle (c'est-à-dire le fichier).

REMARQUE: cette réponse suppose (comme d'autres intervenants l'ont indiqué) que votre déclaration ne fait pas partie d'une fonction.

7
Brandon E Taylor