質問

そのセグメント.BSS,.データその他)の実行可能ファイルの静的変数に格納されるような名前衝突?例えば:


foo.c:                         bar.c:
static int foo = 1;            static int foo = 10;
void fooTest() {               void barTest() {
  static int bar = 2;            static int bar = 20;
  foo++;                         foo++;
  bar++;                         bar++;
  printf("%d,%d", foo, bar);     printf("%d, %d", foo, bar);
}                              }

まコンパイルの両方のファイルにリンクさせることで主るfooTest()およびbarTest繰り返し、printf算値。う意味があるので、fooとbarの変数は現地の翻訳ます。

ものに保管配?

ている場合がありますことを想定するツールチェーンが出力ファイルをELF形式です。このことから、 信じる ることが する一部のスペースの貸し出しの実行ファイル用の静的変数です。
議論の目的能としてのGCCのツールチェーン.

役に立ちましたか?

解決

お統計行に依存してい ゼロの初期化 います。 ゼロの初期化 静的データがありますので、 .BSS(ブロックの開始によるシンボル), 不 ゼロの初期化 データの入っていた .データ

他のヒント

プログラムが読み込み、組織の異なるセグメント一つのセグメント データセグメント.データセグメントは、さらにサブパ

初期化されたデータセグメント: すべてのグローバル静的および定データが格納されています。
初期化されていないデータセグメント(BSS): すべての初期化されていないデータが格納されこのセグメント

ここでは、図の説明このコンセプト:

enter image description here


こちらは非常に良いリンクを説明するこれらのコンセプト

http://www.inf.udec.cl/~leo/teoX.pdf

実際、変数のタプル(貯蔵、範囲、種類、住所、値):

storage     :   where is it stored, for example data, stack, heap...
scope       :   who can see us, for example global, local...
type        :   what is our type, for example int, int*...
address     :   where are we located
value       :   what is our value

地域の範囲が地元の並進ユニット(ソースファイル)は、機能ブロックの場所により、定義されています。を可変に見える以上の機能、それは間違いなくいずれかである必要がありいずれかのデータまたはBSS域かどうかに応じて、その明示的に初期化されない。そのscopedそこから全ての機能(s)や機能(s)内のソースファイルです。

の保存場所のデータを実装に依存します。

しかし、その意味 静的 は"内部連携".これにより、シンボル 内部 の作成ユニット(foo.c,バーがあります。c)には参照できません外を作成ユニットです。りすることはできない名前の衝突.

とは思っていないが衝突.静的にファイルレベル(外部機能の変数として地域の現在の編集部(ファイル).なんてことはありません見える以外に現在のファイルになっています。

静的内部の機能が異なる変数は、関数をかけて食べるという習慣があり、その値は全体を通して保持され話する機能です。

有効な、静的は異なるものであるとの考え方によって同じ場所に設置します。にoth場合ただし、制限されている視認性の変動防止の名前空間衝突で

とはいえ、そのことは両輪で進めていくことに格納されるデータが初期化されています。のBSSもたちのためのバイト-セット-<something> 開催される変数ではないのに初期化されます。

どのようなデータベースで objdump -Sr

実際に理解しようを理解しなければならなリンカー移動等の円滑化の促進ことがなければ、今回の触れることが考えら これらの最初.

ようにして解析Linux x86-64ELF例を見なし:

#include <stdio.h>

int f() {
    static int i = 1;
    i++;
    return i;
}

int main() {
    printf("%d\n", f());
    printf("%d\n", f());
    return 0;
}

コンパイル:

gcc -ggdb -c main.c

ンジニアリング、逆アセンブル、コード:

objdump -Sr main.o
  • -S decompilesのコードのオリジナルソースが混在
  • -r を示して情報移転

内decompilationの f い:

 static int i = 1;
 i++;
4:  8b 05 00 00 00 00       mov    0x0(%rip),%eax        # a <f+0xa>
        6: R_X86_64_PC32    .data-0x4

.data-0x4 することが最初のバイトの .data セグメント

-0x4 があるので使っていRIPは相対で、この %rip の指導- R_X86_64_PC32.

が必要ですのでRIPを 以下の 指導を開始する4バイトの後に 00 00 00 00 では何を得移転を行います。についてご説明してこの詳細: https://stackoverflow.com/a/30515926/895245

そして、このソース i = 1 て同様の解析を行っている:

  • static int i = 0.bss
  • static int i = 1.data

"グローバルな、静的な"地域:)

が複数のメモリ領域はC++

  • ヒープ
  • 無料店
  • スタック
  • グローバル&静
  • const

こちらの 詳細は不明な点があれば、ここでお答え

により、プラットフォームやコンパイラがいます。一部のコンパイラの店舗に直接コードセグメント静的変数は、常にのみアクセスの現在の翻訳単位の名称はこのように輸出された理由は名前の衝突なが発生します。

データ宣言された集大成単位のうちきます。BSSはます。データのファイルを出力します。InitialisedデータBSS,uninitalisedます。

の違いを静的およびグローバルデータ付きのシンボル情報をファイルです。コンパイラが含まのシンボル情報だけのグローバル情報など。

リンカーを尊重し、この情報です。シンボル情報を静的変数には破棄または難号化したように静的変数で参照されるもの(またはデバッグシンボルごすことができました。でない場合での集計単位が影響を受けてのリンカー解決のローカル参照です。

静的変数に格納データセグメントまたはコードセグメントしています。
を確認することができませんので、あらかを割り当てスタックやヒープ.
ありませんリスクの衝突で static キーワードの定義の範囲の変数をファイルまたは機能の衝突があり、コンパイラ/リンカーに警告するようです。
素敵な

でもこの問題は少し古いが、誰もいないポイントは有益な情報:チェックによmohit12379'を説明する店舗の静的変数と同じ名前のシンボルテーブル:http://www.geekinterview.com/question_details/24745

んでobjdump、gdb、こちらのは、何を取得します:

(gdb) disas fooTest
Dump of assembler code for function fooTest:
   0x000000000040052d <+0>: push   %rbp
   0x000000000040052e <+1>: mov    %rsp,%rbp
   0x0000000000400531 <+4>: mov    0x200b09(%rip),%eax        # 0x601040 <foo>
   0x0000000000400537 <+10>:    add    $0x1,%eax
   0x000000000040053a <+13>:    mov    %eax,0x200b00(%rip)        # 0x601040 <foo>
   0x0000000000400540 <+19>:    mov    0x200afe(%rip),%eax        # 0x601044 <bar.2180>
   0x0000000000400546 <+25>:    add    $0x1,%eax
   0x0000000000400549 <+28>:    mov    %eax,0x200af5(%rip)        # 0x601044 <bar.2180>
   0x000000000040054f <+34>:    mov    0x200aef(%rip),%edx        # 0x601044 <bar.2180>
   0x0000000000400555 <+40>:    mov    0x200ae5(%rip),%eax        # 0x601040 <foo>
   0x000000000040055b <+46>:    mov    %eax,%esi
   0x000000000040055d <+48>:    mov    $0x400654,%edi
   0x0000000000400562 <+53>:    mov    $0x0,%eax
   0x0000000000400567 <+58>:    callq  0x400410 <printf@plt>
   0x000000000040056c <+63>:    pop    %rbp
   0x000000000040056d <+64>:    retq   
End of assembler dump.

(gdb) disas barTest
Dump of assembler code for function barTest:
   0x000000000040056e <+0>: push   %rbp
   0x000000000040056f <+1>: mov    %rsp,%rbp
   0x0000000000400572 <+4>: mov    0x200ad0(%rip),%eax        # 0x601048 <foo>
   0x0000000000400578 <+10>:    add    $0x1,%eax
   0x000000000040057b <+13>:    mov    %eax,0x200ac7(%rip)        # 0x601048 <foo>
   0x0000000000400581 <+19>:    mov    0x200ac5(%rip),%eax        # 0x60104c <bar.2180>
   0x0000000000400587 <+25>:    add    $0x1,%eax
   0x000000000040058a <+28>:    mov    %eax,0x200abc(%rip)        # 0x60104c <bar.2180>
   0x0000000000400590 <+34>:    mov    0x200ab6(%rip),%edx        # 0x60104c <bar.2180>
   0x0000000000400596 <+40>:    mov    0x200aac(%rip),%eax        # 0x601048 <foo>
   0x000000000040059c <+46>:    mov    %eax,%esi
   0x000000000040059e <+48>:    mov    $0x40065c,%edi
   0x00000000004005a3 <+53>:    mov    $0x0,%eax
   0x00000000004005a8 <+58>:    callq  0x400410 <printf@plt>
   0x00000000004005ad <+63>:    pop    %rbp
   0x00000000004005ae <+64>:    retq   
End of assembler dump.

こちらはobjdump結果

Disassembly of section .data:

0000000000601030 <__data_start>:
    ...

0000000000601038 <__dso_handle>:
    ...

0000000000601040 <foo>:
  601040:   01 00                   add    %eax,(%rax)
    ...

0000000000601044 <bar.2180>:
  601044:   02 00                   add    (%rax),%al
    ...

0000000000601048 <foo>:
  601048:   0a 00                   or     (%rax),%al
    ...

000000000060104c <bar.2180>:
  60104c:   14 00                   adc    $0x0,%al

ということは、その言は、四つの変数内データセクションイベントに同じ名前が異なるオフセットされます。

これはどのように理解しやすい):

stack, heap and static data

の答えをもつことになるかもしれないのコンパイラなのかも知れません。を編集したいご質問ご注意いただきたいものという概念セグメントのない存ISO CやISO C++).たとえば、Windowsで実行可能な行シンボル名です。One'foo'がオフセット0x100、その他のも0x2B0、コードの両面から翻訳単位の集約された知る-オフセット"の"foo.

うに変更され、独立して、しばしたいということではないかと思われ他の開発するために包むだけで、あっという間に名前空間

りますが、既にご存知のいずれかで店bss(ブロックの開始記号と呼ばれる初期化されていないデータセグメントまたは初期化されたデータセグメント

き、簡単な例

void main(void)
{
static int i;
}

上記の静的変数が初期化されませんように初期化されていないデータセグメント(bss).

void main(void)
{
static int i=10;
}

もちろんで初期化される10のように初期化されたデータセグメント

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top