web-dev-qa-db-fra.com

Global C / C ++ vs global statique

Duplicata possible:
Statique vs global

Je suis confus quant aux différences entre les variables globales globales et statiques. Si statique signifie que cette variable n'est globale que pour le même fichier, alors pourquoi dans deux fichiers différents, le même nom provoque une collision de noms?

Quelqu'un peut-il expliquer cela?

50
Vladp

Les variables globales (pas static) sont là lorsque vous créez le .o fichier disponible pour l'éditeur de liens pour une utilisation dans d'autres fichiers. Par conséquent, si vous avez deux fichiers comme celui-ci, vous obtenez une collision de noms sur a:

a.c:

#include <stdio.h>

int a;

int compute(void);

int main()
{
    a = 1;
    printf("%d %d\n", a, compute());
    return 0;
}

avant JC:

int a;

int compute(void)
{
    a = 0;
    return a;
}

car l'éditeur de liens ne sait pas lequel des a globaux utiliser.

Cependant, lorsque vous définissez des globaux statiques, vous dites au compilateur de ne conserver la variable que pour ce fichier et de ne pas en informer l'éditeur de liens. Donc, si vous ajoutez static (dans la définition de a) aux deux exemples de codes que j'ai écrits, vous n'obtiendrez pas de collisions de noms simplement parce que l'éditeur de liens ne sait même pas qu'il existe un a dans l'un des fichiers:

a.c:

#include <stdio.h>

static int a;

int compute(void);

int main()
{
    a = 1;
    printf("%d %d\n", a, compute());
    return 0;
}

avant JC:

static int a;

int compute(void)
{
    a = 0;
    return a;
}

Cela signifie que chaque fichier fonctionne avec son propre a sans connaître les autres.


En remarque, il est correct d'en avoir un static et l'autre pas tant qu'ils sont dans des fichiers différents. Si deux déclarations se trouvent dans le même fichier (lire unité de traduction ), une static et une extern, voir - cette réponse .

82
Shahbaz

Un nom statique dans chaque fichier devrait pas provoquer des collisions de noms. Si vous voyez cela, veuillez publier un code de démonstration (court) le montrant, ainsi que le compilateur exact que vous utilisez afin que nous puissions vérifier correctement le code et en supposant qu'il est correct, vilipender correctement le compilateur.

Juste FWIW, la méthode préférée en C++ consiste à utiliser un espace de noms anonyme à la place:

namespace { 
    int not_a_static_variable;
}

En toute honnêteté, non, je ne peux pas souligner beaucoup d'avantages objectifs à cela ...

8
Jerry Coffin