Je veux savoir pourquoi nous ne pouvons pas accéder aux variables ces fonctions déclarées à l'intérieur de l'extérieur de la fonction? Il est techniquement possible d'y accéder car ils mettent dans le segment .data tout comme les variables globales / statiques. Quelle est également la différence entre une variable globale et une variable globale statique?

J'ai un fichier C comme suit:

int global_n =1;
static int global_static_n=2;

int main(){
    int local_n=3;
    static int local_static_n=4;
    return 0;
}

void test(){
    global_n=9;
    global_static_n=8;
    //local_n=7;
    //local_static_n=6;
}

Je le compile et le lie par la commande GCC suivante:

gcc -Wall -m32 -nostdlib main.c -o main.o

Je le démonte par les commandes OBJDUMP suivantes:

objdump -w -j .text -D -Mi386,addr32,data32,intel main.o
objdump -w -s -j .data main.o

Et obtenez le vidage suivant:

    Disassembly of section .text:

080480f8 <main>:
 80480f8:   55                      push   ebp
 80480f9:   89 e5                   mov    ebp,esp
 80480fb:   83 ec 10                sub    esp,0x10
 80480fe:   c7 45 fc 03 00 00 00    mov    DWORD PTR [ebp-0x4],0x3
 8048105:   b8 00 00 00 00          mov    eax,0x0
 804810a:   c9                      leave  
 804810b:   c3                      ret    

0804810c <test>:
 804810c:   55                      push   ebp
 804810d:   89 e5                   mov    ebp,esp
 804810f:   c7 05 00 a0 04 08 09 00 00 00   mov    DWORD PTR ds:0x804a000,0x9
 8048119:   c7 05 04 a0 04 08 08 00 00 00   mov    DWORD PTR ds:0x804a004,0x8
 8048123:   90                      nop
 8048124:   5d                      pop    ebp
 8048125:   c3 


Contents of section .data:

804a000 01000000 02000000 04000000

Je peux voir que local_static_n a mis un segment .data comme global_static_n et global_n. Si je décommente les lignes suivantes, j'obtiendrai les erreurs:

local_n=7;
local_static_n=6;
error: ‘local_n’ undeclared (first use in this function)
error: ‘local_static_n’ undeclared (first use in this function)
0
Splash 1 mai 2017 à 16:23

3 réponses

Meilleure réponse

Si static est utilisé dans une portée d'espace de noms (c'est-à-dire en dehors des fonctions et des classes), alors la variable respective est visible pour cette unité de traduction uniquement, et pas pour les autres unités de traduction. Cette construction est utilisée pour éviter les conflits de noms non intentionnels de variables globales définies dans différentes unités / bibliothèques de traduction. C'est ce qu'on appelle le "lien interne"

Si static est utilisé pour une variable dans une fonction, cette variable a une durée de stockage statique, mais elle n'est visible qu'à l'intérieur de la fonction, pas à l'extérieur.

Notez que cette "visibilité" limite simplement le compilateur lors de l'accès à la variable via son nom. Bien sûr, une fonction peut renvoyer ou exposer d'une autre manière l'adresse des variables static d'autres manières; pourtant la variable elle-même n'est pas visible pour le compilateur en dehors des portées mentionnées ci-dessus.

3
Stephan Lechner 1 mai 2017 à 13:39

Je veux savoir pourquoi nous ne pouvons pas accéder aux variables déclarées à l'intérieur des fonctions depuis l'extérieur de la fonction? Il est techniquement possible d'y accéder car ils mettent dans le segment .data tout comme les variables globales / statiques.

Il n'y a aucun problème technique à le faire fonctionner comme vous le souhaitez. Cependant, les concepteurs du langage C ne voulaient pas qu'il fonctionne de cette façon. Les limitations sont là exprès.

Le masquage d'informations est une technique pour faciliter le raisonnement sur un programme en limitant explicitement l'accès à certaines données. Voici un exemple de la façon de procéder.

1
Bo Persson 1 mai 2017 à 14:31

Les variables statiques ne sont accessibles que dans la portée où elles sont déclarées. Cependant, si vous avez vraiment besoin d'y accéder:

#include <stdio.h>

int global_n =1;
static int global_static_n=2;

void test(int* pStatic);

int main(){
    int local_n=3;
    static int local_static_n=4;
    printf("local static %d\n",local_static_n);
    test(&local_static_n);
    printf("local static %d\n",local_static_n);
    return 0;
}

void test(int* pStatic){
    *pStatic=5;
    global_n=9;
    global_static_n=8;
    //local_n=7;
    //local_static_n=6;
}

Cependant, cela n'est pas recommandé. Si vous souhaitez accéder à une variable statique, vous devriez peut-être stocker les données dans une portée différente, quelque part où votre fonction et un autre code peuvent y accéder.

0
Paul Bentley 1 mai 2017 à 13:36