2013-12-10 17 views
9

私は、次のCコードを持っている:Cでは、なぜ0に初期化された変数は "nm"で初期化されていないと報告されますか?

//declared at the beginning of the CAStar.c file: 
    int TERRAIN_PASSABLE = 1; 
    int TERRAIN_IMPASSABLE = 0; 
    int TERRAIN_SOME_WHAT_PASSABLE = 2; 

を私は、彼らがゼロ以外の値を持っている場合は、これらの変数のいずれかのために、彼らはタイプ「D」(初期化)としてthe "nm" commandによって報告されていることに気付きました:

_TERRAIN_PASSABLE   |00000008| D | 
_TERRAIN_SOME_WHAT_PASSABLE|00000004| D | 

ただし、0に初期化されるものを "B"(初期化されていない)として報告される:

_TERRAIN_IMPASSABLE  |00000000| B | 

なぜ初期化「との間の差0 "と" 0以外の何かで初期化 "?

+2

OSからのゼロメモリを期待してコンパイラがヒープ変数を0に初期化しない最適化しかし、推測。 – ypnos

+0

@ypnosまあ、正直言って私はkinddaも同様の行に沿って考えた。しかし、私はこれらの変数のうちの1つを実際には初期化しないようにしました(ちょうど「int TERRAIN_SOME_WHAT_PASSABLE;」)。変数の周りのこの時間は "C"と報告されたので、0で初期化した場合と同じではありません(0以外で初期化した場合と同じではありません)。 –

+0

ld.soはすべてを0に初期化するためです。あなたのアプリケーションのランタイムメモリ割り当て(@ypnos)とは関係ありません。つまり、実行時リンカーが変数を特別なものに設定する必要はありません。 –

答えて

5

これは、BSSがどのように動作し、どのように使用されるかについて多かれ少なかれです。 Bは変数がBSSセクションに置かれることを意味します(そして、あなたは正しくありません。これは初期化されていないデータセクションです)。 Dはシンボルが初期化されたデータセクションに置かれていることを意味します。

たとえば、thisを読むと、BSSの仕組みとそれがどのように使用されているかについて詳しく知ることができます。

+1

私はBSSを初期化していないということは、実際にはゼロで初期化されているので混乱していると思います。多くのコンパイラでは、本当に初期化されていない '.no_init'セクションなどにデータを配置することができます。 – user694733

+0

ありがとう、私は今それを得る。基本的には、「デフォルト値を持つすべての変数があります」リストには、実際のデフォルト値も含まれていないため、スペースを節約できます(右?) –

+0

@ user694733同じことを考えていました。より表現力豊かな、「初期化されていない」はちょっと混乱します。 –

4

ほとんどの場合、これらの変数はファイルスコープで宣言され、の静的格納期間はになります。

静的格納期間を持つすべての変数は、最適化の目的で、コンパイラ/リンカーによって2つのカテゴリにソートされます.0に初期化されるか、または別のものに初期化されます。ゼロに初期化された変数は、通常.bssと呼ばれるメモリセグメントに配置され、別の値に初期化された変数は.dataに配置されます。

.bss変数は、隣接するメモリに割り当てられている場合は、はるかに高速に初期化できます。基本的には、単一のmemsetで初期化されます。また、必要なROMの量も減ります。 Releated question with details.

EDIT

変数は、C言語でのルールがありますので明記(C11 6.7.9/10)そうである初期化されていないの下で終わる.bssの理由は「上がらないすべての静的記憶域期間変数プログラマが明示的に初期化したもの(初期化されていない)は0に初期化されます

関連する問題