Sizeof (char)! = 1 veya en azından CHAR_BIT> 8 olan makineler var mı?


93

Makineler (veya derleyiciler) var sizeof(char) != 1mı , nerede ?

Mu C99 standart söylüyor sizeof(char)standart uygunluk uygulanmasına ilişkin tam olarak 1 OLMALIDIR? Varsa, lütfen bana bölüm numarasını ve alıntıyı verin.

Güncelleme: Baytları adresleyemeyen (minimum okuma 4 bayt, hizalı), ancak yalnızca 4 baytlık ( uint32_t) bir makinem (CPU) varsa, bu makine için derleyici sizeof(char)4'ü tanımlayabilir mi? sizeof(char)1 olacak, ancak char 32 bit olacak ( CHAR_BITmakrolar)

Güncelleme2: Ancak sonucun boyutu BYTES DEĞİLDİR! CHAR boyutudur. Ve char 2 bayt veya (olabilir) 7 bit olabilir?

Güncelleme3: Tamam. Tüm makinelerde var sizeof(char) == 1. Ama hangi makinelerde var CHAR_BIT > 8?


4
C99 standardına uyum konusunda endişeliyim. C99 derleyicileriyle yakın çalışıyorum
osgx

2
Unicode daha da önemli hale geldikçe, char( wchar. Yerine) Unicode karakterleri kullanan standart olmayan derleyiciler gelebilir . Standart sizeof(char)1 olması gerektiğini söylese bile , bu varsayıma güvenmem.
Chip Uni

14
sizeof (char) 'un 1, unicode veya değil, C derleyicisi yoktur.
nos

6
@Chip: sizeof(char)char 32 bit olsa bile (bazı sistemlerde olduğu gibi) her zaman 1'dir. C'nin çok eğlenceli siğilleri var.
Nick Bastin

2
C standardının tüm sürümleri CHAR_BIT'in en az 8 olmasını gerektirir; CHAR_BIT == 7 olamaz ve standartlara uygun olamazsınız. Bununla birlikte, makinelerin CHAR_BIT> 8'e sahip olması mükemmel bir şekilde mümkün. Eski Cray makinelerinin yaptığına inanıyorum ( sizeof(char) == sizeof(short) && sizeof(char) == sizeof(int)bunlarda; sizeof(int) == sizeof(long)CHAR_BIT'in 32 veya 64 olup olmadığını hatırlamıyorum ; 32 olduğunu tahmin ediyorum ve ben de düşünüyorum sizeof(long) == 1. (Bir Cray C kılavuzuna bir referans bulabilirsiniz, ancak çevrimiçi erişimi bulamazsınız ).
Jonathan Leffler

Yanıtlar:


91

C99, bölüm 6.5.3.4'te her zaman birdir:

Char tipi, unsigned char veya imzalı karaktere (veya bunun nitelikli bir versiyonuna) sahip bir işlenen uygulandığında sonuç 1 olur.

Düzenleme: Sorunuzun bir parçası değil, ancak Harbison ve Steele'den ilgi için, 3. baskı. (öncesi c99) s. 148:

Bir depolama birimi, bir karakterin kapladığı depolama miktarı olarak alınır; türdeki bir nesnenin boyutu charbu nedenle 1'dir.

Düzenleme: Güncellenen sorunuza yanıt olarak, Harbison ve Steele'den gelen aşağıdaki soru ve cevap konuyla ilgilidir (ibid, Ex. 4, Ch. 6):

Hangi tipin char-2.147.483.648 ile 2.147.483.647 arasında değişen değerleri temsil edebildiği bir C uygulamasına izin verilebilir mi? Öyleyse, sizeof(char) bu uygulamanın altında ne olacak ? En küçük ve en büyük tür aralığı ne olabilir int?

Cevap (ibid, s. 382):

Bir uygulamanın türü temsil etmek için 32 bit kullanmasına izin verilir (gereksiz ise) char. Uygulamadan bağımsız olarak, değeri sizeof(char)her zaman 1'dir.

Bu, baytların 8 bit olduğu ve charbu baytlardan 4'ü olduğu (c99 tanımıyla aslında imkansız, aşağıya bakın) bir durumu özellikle ele almamakla birlikte, bu gerçeği sizeof(char) = 1c99 standardından ve Harbison ve Steele'den her zaman açıktır.

Düzenleme: Aslında (bu güncelleme 2 sorunuza yanıt olarak), c99 ile ilgili sizeof(char) olarak bayt cinsinden, bölüm 6.5.3.4'ten yine:

Sizeof operatörü, işleneninin boyutunu (bayt cinsinden) verir

bu nedenle yukarıdaki alıntıyla birleştirildiğinde, 8 bitlik baytlar ve charbu baytların 4'ü imkansızdır: c99 için bir bayt a ile aynıdır char.

7 bit olasılığından bahsetmenize yanıt olarak char: bu c99'da mümkün değildir. Standardın 5.2.4.2.1 bölümüne göre minimum 8'dir:

Uygulamada tanımlanan değerleri, aynı işaretle gösterilenlere eşit veya daha büyük [vurgu] olacaktır.

- bit alanı olmayan en küçük nesne için bit sayısı (bayt)

 **CHAR_BIT 8**

- işaretli karakter türünde bir nesne için minimum değer

**SCHAR_MIN -127//−(27−1)** 

- işaretli karakter türündeki bir nesne için maksimum değer

**SCHAR_MAX +127//27−1** 

- unsigned char türündeki bir nesne için maksimum değer

**UCHAR_MAX 255//28−1** 

- char türünde bir nesne için minimum değer

**CHAR_MIN**    see below 

- char türünde bir nesne için maksimum değer

**CHAR_MAX**    see below

[...]

Char türündeki bir nesnenin değeri, bir ifadede kullanıldığında işaretli bir tamsayı olarak ele alınırsa, CHAR_MIN'in değeri SCHAR_MIN'inki ile aynı olacak ve CHAR_MAX'ın değeri SCHAR_MAX'ınki ile aynı olacaktır. Aksi takdirde, CHAR_MIN değeri 0 olacaktır ve CHAR_MAX değeri UCHAR_MAX'ınki ile aynı olacaktır. UCHAR_MAX değeri 2 ^ CHAR_BIT - 1'e eşit olmalıdır.


9
Ek not. karakterinizin kaç bit olduğunu söyleyen bir CHAR_BITS makrosu var.
no:

1
Bu harika kitabın tüm verileri Harbison ve Steele's. C: Bir Referans El Kitabı, Üçüncü Baskı, Prentice Hall, 1991
osgx

2
Karakter türleriyle çalıştığınızı biliyorsanız ve dilin 1 büyüklüğünde olmasını gerektirdiğini biliyorsanız, neden her zaman fazlalık sizeof (char) değerini koymak iyi bir fikirdir?

1
(a) ve (c) bunun çözmeyi umamayacağı, hatta çözmeye yaklaşamayacağı çok daha ciddi sonuçları vardır; ayrıca YAGNI. (B) 'deki gibi birine sadece bir kez söylenmesi gerekiyor --- Onlara kodumun her satırında öğretmeme gerek yok. Bununla birlikte, kullanmanın dezavantajları vardır sizeof(char): tartışmak / kontrol etmek / vb. kodlama kurallarınız / standartlarınız / yönergelerinizde, C'yi gerçekten bilip bilmediğinizi ve başka neyin yanlış olabileceğini merak ederek zamanımı boşa harcıyor, görsel / zihinsel / metin satırı "bant genişliğini" alıyor.

1
@Ramashalanka: Evet, derlenen kod eşdeğerdir. Okunabilirlikle ilgili tüm sorunlar ve bunun dışında insanların bahsettiğim kaynak kodunu nasıl kullandıkları. (Ve FWIW, sanırım burada makul bir +1 cevabınız var, yanlış yönlendirilmek için "her zaman sizeof (char) kullan" ifadesini buluyorum ve küçük bir sorun olsa bile benim için sıcak bir düğme sorunu var.)

21

sizeof(char)4 olan makine yoktur . Her zaman 1 bayttır. Bu bayt 32 bit içerebilir, ancak C derleyicisi söz konusu olduğunda, bu bir bayttır. Daha fazla ayrıntı için, aslında sizi C ++ SSS 26.6'ya yönlendireceğim . Bu bağlantı onu oldukça iyi kapsıyor ve C ++ 'nın tüm bu kuralları C'den aldığından oldukça eminim. Ayrıca 8 bitten büyük karakterler için comp.lang.c FAQ 8.10'a da bakabilirsiniz .

Upd2: Ama sonucun sizeof bir BYTES DEĞİLDİR! CHAR boyutudur. Ve char 2 bayt veya (olabilir) 7 bit olabilir?

Evet, bayttır. Tekrar söylememe izin ver. sizeof(char)C derleyicisine göre 1 bayttır. İnsanların bir bayt (8 bit) dedikleri şey, C derleyicisinin bayt dediği şeyle aynı olmak zorunda değildir. Bir C bayttaki bit sayısı makine mimarinize göre değişir. Ayrıca en az 8 olması garantilidir.


3
Lütfen!!! C ++, C'den (C99) gerçekten FARKLI bir dildir. Bu soru yalnızca C ile ilgilidir.
osgx

<strike> Makine / CPU 8 bit bayta erişemediğinde ne yapabilirim? Hizalanmamış erişim yasaktır. </strike> (x86 malloc bile hizalanmış verileri döndürür ve belleği 4 baytlık katlar halinde tahsis eder.) <strike> O zaman CHAT_BIT 8'den büyük olacaktır. Evet, bu tür platformlar oldukça özel olabilir. </ Strike >
osgx

11
@osgx, insanlar C ve C ++ 'yı karıştırmaya çalıştığında senin yaptığın kadar çığlık atma eğilimindeyim. Ama bu durumda bir C ++ SSS girişinin C için de aynı derecede geçerli olduğunu düşünüyorum .
Michael Kristofik

3
"8 bit" için doğru isim sekizlidir. C Standardı, karakter boyutu olan bir nesne için "bayt" kelimesini kullanır. Diğerleri "bayt" kelimesini farklı şekillerde kullanabilir, genellikle "sekizli" anlamına geldiklerinde, ancak C (ve C ++ veya Amaç-C) 'de "bir karakterin boyutunda nesne" anlamına gelir. Bir karakter 8 bitten fazla veya birden fazla sekizli olabilir, ancak her zaman bir bayttır.
gnasher729

9

PDP-10 ve PDP-11 idi.

Güncelleme: PDP-10 için C99 derleyicileri yoktur.

Bazı Analog Cihazlar 32-bit SHARC DSP modellerinde CHAR_BIT = 32 ve TMS32F28xx'den Texas Instruments DSP'de CHAR_BIT = 16 olduğu bildirilmektedir .

Güncelleme: CHAR_BIT = 9 ile PDP-10 için GCC 3.2 vardır (bu arşivde include / limits.h'yi kontrol edin).


1
Benzer ama C olmayan dillerin uygulamalarını C ile karıştırmayın. Hatta "C99 standardına uyum konusunda endişeliyim. C99 derleyicileriyle yakın çalışıyorum" dediniz.

2
@Roger: GCC'de hata olarak kabul edilen aşırı uç durumlarla uğraşmadığınız sürece GCC3'ü C99 uyumlu değil olarak adlandırmak adil değil.
Joshua

1
@Joshua, Roger'ın K&R ve pcc tarihi derleyicileri hakkında söylediğini düşünüyorum. Ayrıca, bu bağlantı noktasıyla derlendiğinde, C99 uyumluluk testi PDP-10 üzerinde çalıştırılmadan önce C99 uyumlu olduğunu iddia etmek adil değil (taşıma sırasında ve makinenin kendisinden hatalar olabilir). Ancak x86'da GCC3.2 gibi C99 standardına yakın olması beklenebilir.
osgx

1
@Joshua: C99'da CHAR_BIT değerinin 8'den büyük olmasına izin verilir, ancak sizeof (char) hala 1 olmalıdır (ve bu yorumu bıraktığımda bu cevap çok farklıydı). GCC3'ü uyumlu olmayan olarak aramıyorum ve C89 burada aynı gereksinimi yerine getiriyor, BTW. Osgx'in C99 uyumluluğu konusunda endişeli olduğunu ve C99 derleyicilerini kullandığını söyleyen o metni aktardım, o halde C99 olmayan derleyiciler için neden endişeleniyor?

2
PDP-10 GCC'nin yazarı burada. CHAR_BIT 9, ancak sizeof (char) hala 1.
Lars Brinkhoff
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.