web-dev-qa-db-fra.com

variables globales statiques et externes en C et C ++

J'ai fait 2 projets, le premier en C et le second en C++, tous deux fonctionnent avec le même comportement.

Projet C:

header.h

int varGlobal=7;

main.c

#include <stdio.h>
#include <stdlib.h>
#include "header.h"

void function(int i)
{
    static int a=0;
    a++;
    int t=i;
    i=varGlobal;
    varGlobal=t;
    printf("Call #%d:\ni=%d\nvarGlobal=%d\n\n",a,i,varGlobal,t);
}

int main() {
    function(4);
    function(6);
    function(12);
    return 0;
}

Projet C++:

header.h

int varGlobal=7;

main.cpp

#include <iostream>
#include "header.h"
using namespace std;

void function(int i)
{
    static int a=0;
    int t=i;
    a++;
    i=varGlobal;
    varGlobal=t;
    cout<<"Call #"<<a<<":"<<endl<<"i="<<i<<endl<<"varGlobal="<<varGlobal<<endl<<endl; 
}

int main() {
    function(4);
    function(6);
    function(12);
    return 0;
}

J'ai lu que les variables globales sont extern par défaut et en C et statique par défaut en C++; alors pourquoi le code C++ fonctionne-t-il?

Je veux dire int varGlobal = 7; est identique à static int varGlobal = 7; et s'il est statique, il ne peut être utilisé que dans le fichier déclaré, non?

26
Cristi

Les variables globales ne sont ni extern ni static par défaut sur C et C++. Lorsque vous déclarez une variable en tant que static, vous la limitez au fichier source actuel. Si vous la déclarez comme extern, vous dites que la variable existe, mais qu'elle est déclarée ailleurs, et si vous ne la déclarez pas ailleurs (sans le mot clé extern), vous obtiendrez une erreur de lien (symbole introuvable).

Votre code se cassera lorsque vous aurez plus de fichiers source, y compris cet en-tête, au moment du lien, vous aurez plusieurs références à varGlobal. Si vous le déclarez comme static, il fonctionnera avec plusieurs sources (je veux dire, il compilera et liera), mais chaque source aura son propre varGlobal.

Ce que vous pouvez faire en C++, que vous ne pouvez pas faire en C, est de déclarer la variable comme const sur l'en-tête, comme ceci:

const int varGlobal = 7;

Et inclure dans plusieurs sources, sans casser les choses au moment du lien. L'idée est de remplacer l'ancien style C #define pour les constantes.

Si vous avez besoin d'une variable globale visible sur plusieurs sources et non const, déclarez-la comme extern dans l'en-tête, et déclarez-la à nouveau, cette fois sans le travail de clé externe, sur un fichier source:

En-tête inclus par plusieurs fichiers:

extern int varGlobal;

Dans l'un de vos fichiers source:

int varGlobal = 7;
76
fbafelipe

Quand vous #include un en-tête, c'est exactement comme si vous mettiez le code dans le fichier source lui-même. Dans les deux cas, la variable varGlobal est définie dans la source, elle fonctionnera donc quelle que soit la façon dont elle est déclarée.

Comme indiqué dans les commentaires, les variables C++ à la portée du fichier ne sont pas statiques même si elles seront affectées au stockage statique. Si la variable était un membre de classe par exemple, elle devrait être accessible aux autres unités de compilation dans le programme par défaut et les membres non-classe ne sont pas différents.

6
Mark Ransom