C ++: bool neden 8 bit uzunluğundadır?


132

C ++ 'da, bool türünün neden 8 bit uzunluğunda olduğunu (benim sistemimde) merak ediyorum, burada boole değerini tutmak için yalnızca bir bit yeterlidir?

Bunun performans nedenlerinden dolayı olduğuna inanırdım, ama sonra yazmaçların 32 veya 64 bit genişliğinde olduğu 32 bit veya 64 bitlik bir makinede, performans avantajı nedir?

Yoksa bu 'tarihsel' nedenlerden sadece biri mi?


9
Sistemimde bool 8 bit değil. Bu 4 bayt, int ile aynı.
Brian Neal

21
son ne zaman biri, biz erdi neyi sen düşünme düşünce std :: vector <bool>, en nefret stl "özelliği" Hiç =)
Viktor Sehr

1
jldupont, sanırım beni yanlış anladın. sizeof(bool)4 nerede olacak bir sistem istiyordum. Msvc'nin 32-bit bool'ları olduğuna yemin edebilirdim, ama sadece denedim ve olmadı.
avakar

7
Dürüst olmak gerekirse, sorun, vector<bool>zekice davranmaya ve boolleri parçalara ayırmaya çalışması değil, bunu yapmaya ve kendini bir STL kabı olarak gizlemeye çalışması değil . Düz bir bit seti, aynı zamanda bir STL kabı gibi görünmediği sürece iyi olurdu.
jalf

2
@avakar - C ++ boolveri türünü, tanımlanmış olan Windows BOOLtürü ile karıştırıyor olabilirsiniz long. Yani sizeof(bool) != sizeof(BOOL), eminim ki çok fazla kafa karışıklığına (ve muhtemelen çok sayıda hataya) neden olur. Özellikle de vardır çünkü booleanve BOOLEANrumuzudur Windows typedefs, unsigned char. Ayrıca, bool1 bayt olması yaygın olsa da, C ++ standardının özellikle sizeof(bool)daha büyük olabileceğini belirten bir nota sahip olduğunu unutmayın .
Michael Burr

Yanıtlar:


219

Çünkü her C ++ veri türü adreslenebilir olmalıdır.

Tek bir bit için nasıl bir işaretçi yaratırsınız? Yapamazsın. Ama edebilir bir bayt bir gösterici oluşturun. Dolayısıyla, C ++ 'daki bir boole, genellikle bayt boyutundadır. (Daha büyük olabilir. Bu uygulamaya bağlıdır. Asıl mesele, adreslenebilir olması gerektiğidir, bu nedenle hiçbir C ++ veri türü bir bayttan daha küçük olamaz)


7
"bayt" adresleme mimari bir seçimdir (hw seviyesi): farklı bir "adresleme birimi" ile bir sistem çok iyi tasarlanabilir. Yaygın işlemciler için, bir "baytı" adreslemek, harici bellekten bir "bayttan" daha fazlasını getirerek sonuçlanır: bu, verimlilik nedenlerinden kaynaklanmaktadır.
jldupont

8
Evet, bu bir donanım seçimi ve eğer donanım buna izin veriyorsa, bool boyutu değişebilir. Ancak OP, bir bool'un neden 8 bit genişliğinde olduğunu sordu ve böyle olduğu sistemlerde, bunun nedeni genellikle CPU'nun yalnızca 8 bitlik baytları adresleyebilmesidir.
jalf

2
@jldupont: İşaretçi adreslerinin baytlardan daha ince taneli olduğu birkaç sistem var (daha önce eski TI TMS34010 / 20'de programlamıştım, bu da bit bazlı işaretçiler kullanıyordu), ancak bunlar AŞIRI DERECEDE nadirdir.
Michael Kohne

1
Ne demek istediğinden emin değilim. Her nesne adreslenebilir olmalı, yani bir nesnenin adresini almak mümkün olmalıdır. Nesnenin kendi adresini kaydetmesi gerekmez. Bir karakter tipik olarak 8 bit genişliğindedir ve 256 karakterden herhangi birini saklamak için yeterlidir, ancak her karakterin ayrıca bellekte bulunduğu yere göre tanımlanan bir adresi vardır. Bu yüzden bir karaktere bir işaretçi yaratabilirsiniz.
jalf

88
Tehlikeli bir benzetme yapabilirsem: Binamda sekiz kat var, ancak Postane bunların farklı adresler olduğunu kabul etmiyor. Yani eğer tamamen kendime bir adres istiyorsam, aslında bir kata sığmış olsam bile tüm binayı kiralamam gerekiyor. Diğer yedi katı "adres depolamak" için kullanmıyorum, adresleri binalara değil binalara atıfta bulunan Postane kuralı nedeniyle onları boşa harcamak zorunda kaldım. C ++ nesnelerinin kendilerine ait bir adresi olmalıdır - teslimattan sonra postayı sıralamak için posta odaları olmamalıdır ;-)
Steve Jessop

39

Hafıza bayt adreslenebilir. Bellekten okunan baytı kaydırmadan veya maskelemeden tek bir biti adresleyemezsiniz. Bunun çok büyük bir sebep olduğunu tahmin ediyorum.


1
Her zaman değil. 8051 MCU, örneğin, bit adreslenebilir yerle 16 byte
Beached

20

Bir booleantür normalde hedef makinenin adreslenebilir belleğinin en küçük birimini takip eder (yani genellikle 8 bitlik bayt).

Belleğe erişim her zaman "yığınlar" halindedir (bu, donanım düzeyinde verimlilik , veri yolu işlemleri içindir): bir boole biti, çoğu CPU sisteminde "tek başına" adreslenemez. Elbette, veriler bir kayıtta saklandığında, bitleri bağımsız olarak işlemek için genellikle özel talimatlar vardır.

Bu nedenle, "boole" temel veri türlerinin kullanımında verimliliği artırmak için "bit paketleme" tekniklerinin kullanılması oldukça yaygındır . enum2 kodlama gücüne sahip (C'de) gibi bir teknik iyi bir örnektir. Çoğu dilde aynı tür bir numara bulunur.

Güncel : mükemmel bir tartışma sayesinde dikkatimi getirildi sizeof(char)==1tarafından tanımında C ++. Bu nedenle, bir "mantıksal" veri türünün adreslenmesi, adreslenebilir belleğin en küçük birimine oldukça bağlıdır (benim fikrimi güçlendirir).


Bununla ilgili bıraktığınız tüm yorumlar için, cevabın en önemli kısmını boolatlamış olmanız etkileyici: Bir tür, en küçük ayrılabilir bellek birimini takip eder çünkü C ++, ona işaretçiler oluşturmanın mümkün olmasını gerektirir . Bu gereklilik olmadan, a bool, mevcut bayt adresli makinelerde bile tek bir bit olarak temsil edilebilirdi.
jalf

1
hmmm ... Biraz adreslenebilen bir CPU mimarisi yapabilirim ... Hatta bunun için bir derleyici vb. yazabilirim. "Bit adreslenebilir" olan özel bir bellek bölgesine (veya her neyse) sahip olabilirim. Hayal gücünün herhangi bir uzantısı ile imkansız değildir.
jldupont

2
Evet ve bu sistemde bool tek bir bit olarak yapılabilir. Ancak OP, "jlduponts varsayımsal CPU'sunda neden bir bool 8 bit genişliğinde" diye sormadı. Mevcut, yaygın, günlük CPU'lar hakkında sorular sordu ve bunlarda bunun nedeni bayt adreslenebilir olmalarıdır.
jalf

4
sizeof (char) == C ++ 'da tanım başına 1, yani donanımınızın yapabilecekleri veya yapamayacakları alakalı değildir. Sizeof (bool) <sizeof (char) olamaz. BTW C ++, en küçük donanım adreslenebilir birime sahip olmak uygun değilse, donanımın adresleyebileceği bazı alt birimleri ele almak için "şişman" bir işaretçiye sahip olabileceğiniz şekilde tanımlanmıştır. Bu, en azından bazı C derleyicilerinde eski sözcük adreslenebilir mimariler için kullanılmıştır.
AProgramcı

@AProgrammer:: sizeof(char)==1 definitionBu benim argümantasyonuma en iyi karşı argüman. Teşekkürler!
jldupont

6

8 bit ile ilgili cevaplar, adreslenebilir en küçük bellek miktarıdır. Ancak, bazı diller için bir bakıma, boolelerde için 1-bit kullanın. Pascal'ın kümeleri bit dizgileri olarak uyguladığını hatırlıyorum. Yani, aşağıdaki set için:

{1, 2, 5, 7}

Bunu hafızanızda bulundurabilirsiniz:

01100101

Elbette, isterseniz C / C ++ 'da benzer bir şey yapabilirsiniz. (Bir grup boole'nin kaydını tutuyorsanız, mantıklı olabilir , ancak gerçekten duruma bağlıdır.)


8
Aslında, C ++ bunu özel kap vektörü <bool> ile yapar - genellikle bir felaket olarak görülür.

C ++ bunu C'den miras alınan "bit alanları" ile de yapar. Bir yapının / sınıfın bir üye değişkenini bildirirken, değeri saklamak için kullanılan bit sayısını bildirebilirsiniz (örneğin, "işaretsiz kısa alan: 3").

@Neil: Neden genellikle bir felaket olarak görülüyor? Performans sorunu mu?
Jérôme

2
@Jerome: Çünkü, bir bit adreslenebilir olmadığından, normal bir şekilde davranamaz vector. Davranış üzerinde kısıtlamalar olduğu için aslında STL tipi bir kap değildir. Daha da kötüsü, birisinin hastalıklarına sahip olması boolve vectoronlardan yapmak istemesiyle sorunlara neden olmasıdır . Bu şaşırtıcı bir davranış ve bir dilde istediğin bu değil.
David Thornley

1
@jldupont - böyle bir noktaya bir kez değinmek yeterlidir. Ve C ++, donanımın neler yapabileceğine bakılmaksızın bitlerin adreslenebilir (tersi) olduğunu garanti etmez.

1

Bunun eski olduğunu biliyorum ama 2 sentimi atayım dedim.

Boole veya veri türünüzü bir bit ile sınırlarsanız, uygulamanız bellek kesintisi riski altındadır. Hafızadaki yalnızca bir bit uzunluğundaki hata istatistiklerini nasıl işlersiniz?

Bir iş görüşmesine gittim ve program liderinin bana söylediği ifadelerden biri şöyleydi: "Bir füzeyi fırlatmak için sinyali gönderdiğimizde, kablosuz aracılığıyla bir bit üzerinden basit bir bit gönderiyoruz. Bir bit göndermek son derece hızlı ve biz bu sinyalin olabildiğince hızlı olması gerekiyor. "

Bu, kavramları ve bitleri, baytları ve hata işlemeyi anlayıp anlamadığımı görmek için yapılan bir testti. Kötü bir adamın tek bitlik bir mesaj göndermesi ne kadar kolay olurdu. Ya da aktarım sırasında bit diğer yöne çevrilirse ne olur.


Sor yeni bir soru diğer sorulara cevap olarak soru göndermektir yok.
Igor Jerosimić

6
Bence bu "cevapta" yer alan soru aslında retorik bir sorudur, yani boole'leri bir bit olarak uygulamamamızın nedeni, tek bir bitin hata istatistiklerini işleyememesidir.
Stephen Holt

1
@StephenHolt ama nedeni bu değil ve TBH bu cevabın bir anlamı yok.
doktor

1
...ne? "Hata istatistikleri" ile neyi kastettiğinizi bilmiyorum, CRC veya benzeri, ya da tuzak temsilleri. Ancak her halükarda, daha büyük türler bile "hata istatistikleri" için fazladan "yedek" bitlerini kullanmazlar, çünkü ekstrem ortam kodlayıcıları dışındaki herkes, kodlarının belleği okumadan önce donanımlarının hata algılama / düzeltmeyi işleyebileceğini varsayar. zamanlarını bir şekilde her değişkeni doğrulama bilgisi ya da her neyse doldurarak harcamalarına gerek yoktur. boolDiğer 7 veya 31 bit kesinlikle herhangi bir "hata istatistikleri" için kullanılmadığından, OP'nin makinesinde 8 ve benimkinde 32 bit kullanmasının nedeni bu değil. Bu hiç mantıklı değil
altçizgi_d

1

Bazı gömülü derleyiciler, boole bayraklarını bit paketlemek için kullanılan bir int1 türüne sahiptir (örneğin, Microchip MPU'lar için CCS serisi C derleyicileri). Bu değişkenlerin ayarlanması, temizlenmesi ve test edilmesi, tek komutlu bit düzeyinde talimatlar kullanır, ancak derleyici, diğer yanıtlarda belirtilen nedenlerden ötürü başka hiçbir işleme (örneğin değişkenin adresini almak) izin vermez.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.