2011-10-20 5 views
37

statique Possible en double:
Static vs globalC/C++ global vs global

Je suis confus au sujet des différences entre les variables globales globales et statiques. Si static signifie que cette variable est globale uniquement pour le même fichier, alors pourquoi dans deux fichiers différents le même nom provoque-t-il une collision de noms?

Quelqu'un peut-il expliquer cela?

+4

Poster le code ... – Nawaz

+0

Avez-vous un exemple? – glglgl

+2

Si les deux variables sont déclarées statiques dans des fichiers différents, cela ne devrait pas provoquer de collision de noms.Je viens d'effectuer un test rapide et cela fonctionne comme prévu. Si cela ne fonctionne pas pour vous, veuillez poster le code où il ne fonctionne pas comme prévu, ce que vous attendez et ce que vous obtenez, et quel compilateur vous utilisez. – Kevin

Répondre

65

Les variables globales (pas static) sont là lorsque vous créez le fichier .o 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 nom sur a:

ac:

#include <stdio.h> 

int a; 

int compute(void); 

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

bc:

int a; 

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

parce que l'éditeur de liens ne sait pas quel mondial a s à utiliser. Toutefois, lorsque vous définissez des globals statiques, vous demandez au compilateur de conserver la variable uniquement pour ce fichier et de ne pas en informer l'éditeur de liens. Donc, si vous ajoutez static (dans la définition de a) vous n'obtiendrez les collisions de noms simplement les deux exemples de codes que j'ai écrit, parce que l'éditeur de liens ne sait même pas qu'il y ait un a dans l'un des fichiers:

ac:

#include <stdio.h> 

static int a; 

int compute(void); 

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

bc:

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.


Comme une note de côté, il est correct d'avoir un d'entre eux static et l'autre pas aussi longtemps qu'ils sont dans des fichiers différents. Si deux déclarations sont dans le même fichier (lire unité de traduction), une static et une extern, voir this answer.

+0

Que diriez-vous de déclarer un statique et l'autre non? – Kissaki

+1

@kissaki, si ces déclarations sont dans des fichiers différents, ça va. Le fichier qui a la déclaration statique utiliserait cette variable statique qui est invisible aux autres fichiers. Tous les fichiers qui ont la déclaration de variable non statique utiliseraient la variable globale partagée. – Shahbaz

+0

Si ces deux déclarations, une statique et une externe, sont écrites dans le même fichier (lire l'unité de traduction), voir [cette réponse] (http://stackoverflow.com/a/17043698/912144). – Shahbaz

6

Un nom qui est statique dans chaque fichier doit pas causer des collisions de noms. Si vous voyez cela, veuillez poster (court) le code démo le montrant, avec le compilateur exact que vous utilisez pour que nous puissions vérifier correctement le code et en supposant que c'est correct, vilipender le compilateur.

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

namespace { 
    int not_a_static_variable; 
} 

En toute honnêteté, je ne peux pas souligner à beaucoup d'avantage objectif que si ...

+1

'En toute honnêteté, non je ne peux pas pointer vers beaucoup d'avantage objectif à cela si ...' ... Peut-être ce sujet peut aider d'une certaine manière: [Pourquoi l'espace de noms sans nom est une alternative "supérieure" à statique?] (http://stackoverflow.com/questions/4977252/why-unnamed-namespace-is-a-superior-alternative-to -static) – Nawaz

+5

C++ 11 supprime la dépréciation des objets statiques, de sorte qu'aucune de ces deux méthodes n'est particulièrement "préférée". –

+0

@MikeSeymour: C'est aussi vrai. – Nawaz