Apakah ada mesin, di mana sizeof (char)! = 1, atau setidaknya CHAR_BIT> 8?

93

Apakah ada mesin (atau kompiler), di mana sizeof(char) != 1?

Apakah standar C99 mengatakan bahwa sizeof(char)pada penerapan kepatuhan standar HARUS tepat 1? Jika ya, tolong beri saya nomor bagian dan kutipan.

Pembaruan: Jika saya memiliki mesin (CPU), yang tidak dapat menangani byte (pembacaan minimal adalah 4 byte, selaras), tetapi hanya 4-s dari byte ( uint32_t), dapatkah kompiler untuk mesin ini mendefinisikan sizeof(char)ke 4? sizeof(char)akan menjadi 1, tetapi char akan memiliki 32 bit ( CHAR_BITmakro)

Pembaruan2: Tapi sizeof hasil BUKANLAH BYTES! itu adalah ukuran CHAR. Dan char bisa 2 byte, atau (mungkin) 7 bit?

Pembaruan3: Ok. Semua mesin punya sizeof(char) == 1. Tapi mesin apa yang dimiliki CHAR_BIT > 8?

osgx
sumber
4
Saya khawatir dengan kepatuhan standar C99. Saya bekerja sama dengan kompiler C99
osgx
2
Karena Unicode menjadi lebih penting, mungkin ada kompiler non-standar yang menggunakan karakter Unicode sebagai char(bukan wchar.) Bahkan jika standar mengatakan itu sizeof(char)harus 1, saya tidak akan mengandalkan asumsi itu.
Chip Uni
14
tidak ada kompiler C dimana sizeof (char) bukan 1, unicode atau tidak.
no
6
@Chip: sizeof(char)selalu 1, meskipun char adalah 32-bit (seperti yang terjadi pada beberapa sistem). C memiliki banyak kutil yang menyenangkan.
Nick Bastin
2
Semua versi standar C membutuhkan CHAR_BIT minimal 8; Anda tidak dapat memiliki CHAR_BIT == 7 dan mematuhi standar. Namun, sangat layak bagi mesin untuk memiliki CHAR_BIT> 8. Mesin Old Cray melakukannya, saya percaya ( sizeof(char) == sizeof(short) && sizeof(char) == sizeof(int)pada mereka; Saya tidak ingat sizeof(int) == sizeof(long)apakah CHAR_BIT berusia 32 atau 64; Saya berharap itu 32, dan saya pikir sizeof(long) == 1juga. (Anda dapat menemukan referensi ke, tetapi tidak akses online ke, manual Cray C ).
Jonathan Leffler

Jawaban:

91

Itu selalu satu di C99, bagian 6.5.3.4:

Ketika diterapkan ke operand yang memiliki tipe char, unsigned char, atau signed char, (atau versi yang memenuhi syarat) hasilnya adalah 1.

Sunting: bukan bagian dari pertanyaan Anda, tetapi untuk minat dari Harbison and Steele, edisi ke-3. (pra c99) hal. 148:

Unit penyimpanan dianggap sebagai jumlah penyimpanan yang ditempati oleh satu karakter; charOleh karena itu , ukuran objek tipe adalah 1.

Sunting: Sebagai jawaban atas pertanyaan Anda yang diperbarui, pertanyaan dan jawaban berikut dari Harbison dan Steele relevan (ibid, Keluaran 4 dari Bab 6):

Apakah diperbolehkan untuk memiliki implementasi C di mana tipe chardapat mewakili nilai mulai dari -2,147,483,648 hingga 2,147,483,647? Jika ya, apa yang akan terjadi sizeof(char) dalam penerapan itu? Berapakah rentang tipe terkecil dan terbesar int?

Jawaban (ibid, hlm. 382):

Diijinkan (jika boros) untuk sebuah implementasi menggunakan 32 bit untuk merepresentasikan tipe char. Terlepas dari implementasinya, nilai sizeof(char)selalu 1.

Meskipun ini tidak secara khusus menangani kasus di mana, katakanlah byte adalah 8 bit dan char4 dari byte tersebut (sebenarnya tidak mungkin dengan definisi c99, lihat di bawah), fakta bahwa sizeof(char) = 1selalu jelas dari standar c99 dan Harbison dan Steele.

Edit: Sebenarnya (ini adalah jawaban terhadap pertanyaan Anda upd 2), sejauh c99 yang bersangkutan sizeof(char) adalah dalam byte, dari bagian 6.5.3.4 lagi:

Operator sizeof menghasilkan ukuran (dalam byte) operannya

jadi dikombinasikan dengan kutipan di atas, byte dari 8 bit dan charsebagai 4 dari byte tersebut tidak mungkin: untuk c99 satu byte sama dengan a char.

Sebagai jawaban atas penyebutan kemungkinan 7 bit char: ini tidak mungkin dilakukan di c99. Menurut bagian 5.2.4.2.1 dari standar, minimum adalah 8:

Nilai-nilai yang ditetapkan implementasinya harus sama atau lebih besar [penekanan saya] dalam besarannya dengan yang ditunjukkan, dengan tanda yang sama.

- jumlah bit untuk objek terkecil yang bukan bit-field (byte)

 **CHAR_BIT 8**

- nilai minimum untuk objek bertipe karakter bertanda

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

- nilai maksimum untuk objek bertipe karakter bertanda

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

- nilai maksimum untuk objek bertipe unsigned char

**UCHAR_MAX 255//28−1** 

- nilai minimum untuk objek bertipe char

**CHAR_MIN**    see below 

- nilai maksimum untuk objek bertipe char

**CHAR_MAX**    see below

[...]

Jika nilai objek bertipe char diperlakukan sebagai bilangan bulat bertanda saat digunakan dalam ekspresi, nilai CHAR_MIN harus sama dengan SCHAR_MIN dan nilai CHAR_MAX harus sama dengan SCHAR_MAX. Jika tidak, nilai CHAR_MIN harus 0 dan nilai CHAR_MAX harus sama dengan UCHAR_MAX. Nilai UCHAR_MAX harus sama dengan 2 ^ CHAR_BIT - 1.

Ramashalanka
sumber
9
Catatan tambahan. ada makro CHAR_BITS yang akan memberi tahu Anda berapa banyak bit karakter Anda.
no
1
Data lengkap dari buku hebat ini adalah Harbison and Steele's. C: Manual Referensi, Edisi Ketiga, Prentice Hall, 1991
osgx
2
Jika Anda tahu Anda bekerja dengan tipe karakter dan Anda tahu bahasanya mengharuskan mereka untuk memiliki ukuran 1, mengapa ide yang baik untuk selalu menempatkan ukuran yang berlebihan (char)?
1
(a) dan (c) memiliki konsekuensi yang jauh lebih serius yang tidak dapat diharapkan untuk diselesaikan, atau bahkan mendekati penyelesaian; juga YAGNI. Seseorang seperti dalam (b) hanya perlu diberi tahu sekali --- Saya tidak perlu mengajari mereka di setiap baris kode saya. Namun, ada kekurangan untuk menggunakan sizeof(char): ini adalah item lain untuk diperdebatkan / diperiksa / etc. dalam konvensi / standar / pedoman pengkodean Anda, membuang-buang waktu saya bertanya-tanya apakah Anda benar-benar tahu C dan apa lagi yang mungkin salah, membutuhkan "bandwidth" visual / mental / teks-line.
1
@Ramashalanka: Ya, kode yang dikompilasi sama. Ini semua masalah seputar keterbacaan dan sebaliknya bagaimana orang menggunakan kode sumber yang saya bicarakan. (Dan FWIW, saya pikir Anda memiliki jawaban +1 yang layak di sini, saya hanya menemukan "selalu gunakan sizeof (char)" untuk menjadi salah arah dan masalah hotbutton bagi saya, bahkan jika masalah kecil.)
21

Tidak ada mesin sizeof(char)yang 4. Selalu 1 byte. Byte itu mungkin berisi 32 bit, tetapi sejauh menyangkut compiler C, itu adalah satu byte. Untuk lebih jelasnya, saya sebenarnya akan mengarahkan Anda ke C ++ FAQ 26.6 . Tautan itu mencakupnya dengan cukup baik dan saya cukup yakin C ++ mendapatkan semua aturan itu dari C. Anda juga dapat melihat comp.lang.c FAQ 8.10 untuk karakter yang lebih besar dari 8 bit.

Upd2: Tapi sizeof hasil BUKANLAH BYTES! itu adalah ukuran CHAR. Dan char bisa 2 byte, atau (mungkin) 7 bit?

Ya, ini adalah byte. Biarkan saya katakan sekali lagi. sizeof(char)adalah 1 byte menurut kompiler C. Apa yang disebut orang sehari-hari sebagai byte (8 bit) belum tentu sama dengan apa yang disebut oleh kompilator C sebagai byte. Jumlah bit dalam C byte bervariasi tergantung pada arsitektur mesin Anda. Ini juga dijamin setidaknya 8.

Michael Kristofik
sumber
3
Silahkan!!! C ++ adalah bahasa yang sangat BERBEDA dari C (C99). Pertanyaan ini hanya tentang C biasa.
osgx
<strike> Apa yang dapat saya lakukan jika mesin / CPU tidak dapat mengakses byte 8-bit? Akses tidak selaras dilarang. </ Strike> (Bahkan pada x86 malloc mengembalikan data yang selaras dan mengalokasikan memori dalam kelipatan 4 byte.) <strike> Kemudian CHAT_BIT akan lebih besar dari 8. Ya, platform semacam itu bisa agak istimewa. </ Strike >
osgx
11
@osgx, saya cenderung berteriak seperti yang baru saja Anda lakukan ketika orang mencoba mencampur C dan C ++. Tapi saya pikir dalam kasus ini bahwa satu entri FAQ C ++ berlaku sama baiknya untuk C.
Michael Kristofik
3
Nama yang benar untuk "8 bit" adalah oktet. Standar C menggunakan kata "byte" untuk objek seukuran karakter. Orang lain mungkin menggunakan kata "byte" dengan cara yang berbeda, sering kali berarti "oktet", tetapi dalam C (dan C ++, atau Objective-C) itu berarti "objek seukuran karakter". Char bisa lebih dari 8 bit, atau lebih dari satu oktet, tapi selalu satu byte.
gnasher729
9

PDP-10 dan PDP-11 adalah.

Pembaruan: tidak ada kompiler C99 untuk PDP-10.

Beberapa model Perangkat Analog SHARC DSP 32-bit memiliki CHAR_BIT = 32, dan Texas Instruments DSP dari TMS32F28xx memiliki CHAR_BIT = 16, dilaporkan .

Update: Ada GCC 3.2 untuk PDP-10 dengan CHAR_BIT = 9 (periksa include / limit.h di arsip itu).

osgx
sumber
1
Jangan bingung penerapan bahasa yang mirip-tetapi-bukan-C dengan C. Anda bahkan mengatakan "Saya khawatir dengan kepatuhan standar C99. Saya bekerja sama dengan kompiler C99."
2
@Roger: Tidak adil untuk menyebut GCC3 bukan C99, kecuali Anda berurusan dengan kasus edge ekstrem yang dianggap sebagai bug di GCC.
Joshua
1
@Joshua, saya pikir Roger mengatakan tentang K&R dan kompiler bersejarah pcc. Juga tidak adil untuk mengklaimnya C99 compliant sebelum C99 compliance testsuite dijalankan pada PDP-10, ketika dikompilasi dengan port ini (mungkin ada bug dari porting dan dari mesin itu sendiri). Tapi bisa diharapkan mendekati standar C99 seperti halnya GCC3.2 di x86.
osgx
1
@ Joshua: CHAR_BIT diperbolehkan, di C99, lebih besar dari 8, tetapi sizeof (char) harus tetap 1 (dan jawaban ini jauh berbeda ketika saya meninggalkan komentar itu). Saya tidak menyebut GCC3 tidak patuh, dan C89 membuat persyaratan yang sama di sini, BTW. Saya mengutip teks tersebut untuk mengatakan bahwa osgx adalah orang yang khawatir tentang kepatuhan C99 dan menggunakan kompiler C99, jadi mengapa dia khawatir tentang kompiler non-C99?
2
Penulis PDP-10 GCC di sini. CHAR_BIT adalah 9, tetapi ukuran (char) masih 1.
Lars Brinkhoff