Raisons d'utiliser les fonctions et variables statiques en C

je me demande à propos de l'utilisation de l' static mot-clé comme limite de portée pour les variables dans un fichier, en C.

La norme de façon à construire un programme en C que je vois c'est:

  • avoir un tas de fichiers c définissant les fonctions et les variables, peut-être portée limitée avec static.
  • avoir un tas de fichiers h déclarant les fonctions et éventuellement les variables du fichier c correspondant, pour les autres fichiers c à utiliser. Les fonctions et variables privées ne sont pas publiées dans l'h de fichier.
  • chaque fichier c est compilé séparément dans un fichier O.
  • tous les fichiers o sont reliés ensemble à un fichier de demande.

je vois deux raisons pour déclarer un global static si la variable n'est pas publié dans le h de fichier:

  • on est pour des raisons de lisibilité. Informez les futurs lecteurs, y compris moi-même, qu'une variable n'est pas accessible dans un autre fichier.
  • la deuxième est d'empêcher un autre fichier c dans redeclaring la variable extern. Je suppose que le linker n'apprécierait pas qu'une variable soit à la fois extern et static. (Je n'aime pas l'idée d'un fichier redeclaring une variable appartenant à quelqu'un d'autre que extern, est-ce ok de la pratique?)

pour une autre raison?

en va de Même pour static fonctions. Si le prototype n'est pas publié dans le fichier h, d'autres fichiers peuvent ne pas utiliser la fonction de toute façon, alors pourquoi le définir static? Je peux voir les deux mêmes raisons, mais non plus.

23
demandé sur Gauthier 2010-06-04 15:58:38

6 réponses

lorsque vous parlez d'informer les autres lecteurs, considérez le compilateur lui-même comme un lecteur. Si une variable est déclarée static, qui peut affecter le degré auquel les optimisations se déclenchent.

la Redéfinition d'un static variable extern est impossible, mais le compilateur vous donnera (comme d'habitude) assez de corde pour vous pendre.

Si j'écris static int foo; dans un fichier, et int foo; dans un autre, ils sont considérés comme des variables, bien qu'ayant le même nom et type - le compilateur ne se plaindra pas mais vous serez probablement très confus plus tard en essayant de lire et/ou de déboguer le code. (Si j'écris extern int foo; dans le second cas, il n'y aura pas de lien à moins que je ne déclare un quelque part d'autre.)

les variables globales apparaissent rarement dans les fichiers d'en-tête, mais lorsqu'elles apparaissent, elles doivent être déclarées extern. Si non, en fonction de votre compilateur, vous risquez que chaque fichier source qui inclut cet en-tête déclare sa propre copie du variable: au mieux, cela provoquera une défaillance du lien (symbole à Définition multiple) et au pire, plusieurs cas confus de dépassement.

25
répondu crazyscot 2010-06-04 12:20:23

En déclarant une variable static au niveau du fichier (static à l'intérieur de la fonction a une signification différente) vous interdisez à d'autres unités d'y accéder, par exemple si vous essayez de la variable utiliser à l'intérieur d'une autre unité (déclaré avec extern), linker ne trouvera pas ce symbole.

8
répondu qrdl 2010-06-04 12:43:51

quand vous déclarez un statique fonction l'appel à la fonction est un " appel de proximité "et en théorie il fonctionne mieux qu'un"appel lointain". Vous pouvez utiliser google pour obtenir plus d'information. est ce que j'ai trouvé avec une simple recherche google.

6
répondu INS 2010-06-04 13:07:58

Si une variable globale est déclarée statique, le compilateur peut parfois prendre de meilleures optimisations que si elle n'était pas. Parce que le compilateur sait que la variable ne peut pas être consultée à partir d'autres fichiers source, il peut faire de meilleures déductions sur ce que votre code fait (comme "cette fonction ne modifie pas cette variable"), ce qui peut parfois le faire générer du code plus rapidement. Très peu de compilateurs / linkers peuvent faire ce genre d'optimisations à travers différentes unités de traduction.

1
répondu Adam Rosenfield 2010-06-04 12:19:07

si vous déclarez une variable foo dans le fichier a. c sans le rendre statique, et une variable foo dans le fichier B. c sans le rendre statique, les deux sont automatiquement externes, ce qui signifie que le linker peut se plaindre si vous initialisez les deux, et assigner le même emplacement mémoire s'il ne se plaint pas. Attendez-vous à du plaisir à déboguer votre code.

si vous écrivez une fonction foo () dans le fichier a. c sans la rendre statique, et une fonction foo () dans le fichier B. c sans la rendre statique, le linker peut se plaindre, mais si elle non, tous les appels à foo () appelleront la même fonction. Attendez-vous à du plaisir à déboguer votre code.

0
répondu gnasher729 2014-04-01 06:58:23

mon usage préféré de static est d'être en mesure de stocker des méthodes que je ne vais pas avoir à injecter ou créer un objet à utiliser, la façon dont je le vois, les méthodes statiques privées sont toujours utiles, où public static vous devez mettre plus de temps à penser à ce que vous faites pour éviter ce que crazyscot défini comme, obtenir votre auto trop de corde et accidentellement accrocher soi-même!

j'aime garder un dossier pour les classes Helper pour la plupart de mes projets qui consistent principalement en statique méthodes pour faire les choses rapidement et efficacement à la volée, pas d'objets nécessaires!

-1
répondu Jake Kalstad 2010-06-04 13:51:48