2013-12-10 16 views
9

Aşağıdaki Cı kodu vardır:C, niçin 0 int değişkenine başlattığımı neden "nm" tarafından başlatılmamış olarak bildiriliyor?

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

I (başlatılmış) bir sıfır olmayan değere sahip ise bu değişkenlerin herhangi biri için, bu tip "D" olarak the "nm" command tarafından rapor fark ettik:

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

Bununla birlikte, = 0 başlangıç ​​o "B" (başlatılmamış) olarak rapor edilir:

_TERRAIN_IMPASSABLE  |00000000| B | 

neden başlatıldı" arasındaki fark 0 "ve" ile başka bir şeyle başlatıldı ama 0 "?

+2

Sıfırla başlatılır. Derleyici, OS'den sıfırlanmış belleği beklediği için bir yığın değişkenini sıfıra sıfırlamadığı bir optimizasyon olabilir. bir tahmin olsa da. – ypnos

+0

@ypnos Peki, dürüst olmak gerekirse, bu satırlar boyunca da düşündüm. Ama sonra, bu değişkenlerden birini gerçekten başlatılmamış halde bıraktım (sadece: "int TERRAIN_SOME_WHAT_PASSABLE;"). Değişkenin etrafındaki bu zaman, "C" olarak rapor edildi, yani (yine yine) 0 ile başlatıldıkça aynı değildi (ve aynı zamanda 0 ile başlatılmadıysa). –

+0

Çünkü ld.so her şeyi sıfırlar. Uygulamanızın çalışma zamanı bellek ayırma (@ypnos) ile ilgisi yok - sadece çalışma zamanı bağlayıcısının değişkenleri özel bir şeye ayarlamak zorunda olmadığı anlamına gelir. –

cevap

5

Bu, BSS'nin nasıl çalıştığı ve nasıl kullanıldığı hakkında az çok ilgilidir. B, değişkenin BSS bölümüne yerleştirileceği anlamına gelir (ve doğru değil, başlatılmamış veri bölümüdür). D, sembolün başlatılmış veri bölümüne yerleştirildiği anlamına gelir. B12'nin nasıl çalıştığını ve ne için kullanıldığı hakkında daha fazla bilgi sahibi olmak için this makalesini okuyun.

+1

BSS'nin başlatılmamış halini çağırmanın kafa karıştırıcı olduğunu düşünüyorum çünkü gerçekten sıfır başlatıldı. Birçok derleyici, verileri henüz başlatılmamış olan '.no_init 'bölümüne veya benzeri bir yere yerleştirmeye izin verir. – user694733

+0

Teşekkürler, şimdi anladım. Temelde bir: "işte varsayılan değerlere sahip olan tüm değişkenler var", bu da gerçek varsayılan değerleri içermeyen liste, yerden tasarruf etmek için (sağ?) –

+0

@ user694733 Aynı şeyi düşünüyordum, belki bir şeyler olmalı daha anlamlı, "başlatılmamış" biraz kafa karıştırıcı. –

4

Bu değişkenlerin büyük olasılıkla dosya kapsamı içinde bildirilmesi, statik depolama süresi.

Statik depolama süresi olan tüm değişkenler, en iyi duruma getirme amacıyla, derleyici/bağlayıcı tarafından iki kategoriye ayrılır: 0 olarak başlatılır veya başka bir şeye başlatılır. Sıfıra sıfırlanan değişkenler, genellikle .bss olarak adlandırılan bir bellek segmentine yerleştirilirken, başka bir değere başlatılanlar .data'a yerleştirilir.

Bunun nedeni, bitişik bellekte ayrılırsa .bss değişkeninin çok daha hızlı başlatılabilmesidir. Temel olarak, tek bir memset ile başlatılacaktır. Ayrıca, gerekli ROM miktarını azaltacaktır. Releated question with details.

DÜZENLEME

değişkenler C dilinde bir kural olmadığından belirten (C11 6.7.9/10) muhtemelen başlatılmamış altında sona .bss nedeni 'değiller tüm statik depolama süresi değişkenleri t programcı tarafından açık bir şekilde başlatılır ("başlatılmamış"),