2017-05-01 13 views
-1

私はなぜ関数の外から関数内で宣言された変数にアクセスできないのか知りたいですか?技術的には、グローバル/静的変数のように.dataセグメントを入れたので、それらにアクセスすることは技術的に可能です。また、グローバル変数と静的グローバル変数の違いは何ですか?関数内で宣言された静的変数にアクセスしています

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; 
} 

私はコンパイルして、次のGCCコマンドでそれをリンク:

objdump -w -j .text -D -Mi386,addr32,data32,intel main.o 
objdump -w -s -j .data main.o 
:以下objdumpのコマンドによって、私はそれを逆アセンブル

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

は、私は次のよう Cのファイルを持っています

次のダンプを取得してください:

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 020000000400万

私はlocal_static_nがちょうどglobal_static_nglobal_nよう.dataのセグメントに入れていることがわかります。次の行のコメントを外すと、エラーが表示されます。

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

これらは宣言されている関数にスコープが設定されているため、生成されたアセンブリとは何の関係もありません。言語標準ではどのように定義されていますか?[参照先ページ(http:// en .cppreference.com/w/c/language/scope):* "Cプログラムに現れる各識別子は、スコープと呼ばれるソースコードの不連続な部分だけに見える(つまり使用される) – UnholySheep

答えて

3

staticが名前空間のスコープ(つまり、関数とクラスの外)で使用されている場合、それぞれの変数はこの翻訳単位でのみ表示され、他の翻訳単位では表示されません。この構造体は、異なる翻訳単位/ライブラリで定義されたグローバル変数の意図しない名前の衝突を避けるために使用されます。

staticが関数内の変数に使用されている場合、この変数は静的な記憶期間を持ちますが、関数の内部でのみ表示され、外部では表示されません。

この「可視性」は、名前を介して変数にアクセスするときにコンパイラを制限するだけであることに注意してください。もちろん、関数は他の方法で変数staticのアドレスを返すか他の方法で公開することができます。変数自体は上記のスコープ外のコンパイラには見えません。

0

静的変数は、宣言されているスコープ内でしかアクセスできません。ただし、実際にアクセスする必要がある場合:

#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; 
} 

ただし、これはお勧めしません。静的変数にアクセスする場合は、データを別のスコープに格納し、関数や他のコードがアクセスできる場所に格納する必要があります。

1

私はなぜ関数の外から関数内で宣言された変数にアクセスできないのか知りたいですか?技術的には、グローバル/静的変数のように.dataセグメントを配置するため、アクセスすることは技術的に可能です。

あなたが望むように動作させることに技術的な問題はありません。しかし、C言語を設計している人は、それがそのように動作することを特に望んでいませんでした。制限はそこにある。

情報隠蔽は、明示的に一部のデータへのアクセスを制限することにより、プログラムの理由を簡単にする1つの手法です。これはその方法の一例です。

関連する問題