Bagaimana dengan sejarah typedef sup untuk bilangan bulat dalam program C?

Ini mungkin pertanyaan konyol yang jawabannya mungkin aku harus tahu.

Lima belas tahun yang lalu atau lebih, banyak kode C I'd lihat punya banyak bilangan bulat typedefs di platform-spesifik `#ifdef ini. Tampaknya setiap program atau perpustakaan saya melihat punya mereka sendiri, saling bertentangan typedef sup. Aku't tahu banyak tentang pemrograman di waktu dan sepertinya aneh banyak rintangan untuk melompat melalui hanya untuk memberitahu compiler apa jenis integer yang anda ingin gunakan.

I've menempatkan bersama-sama sebuah cerita dalam pikiran saya untuk menjelaskan apa yang mereka typedefs sekitar, tapi aku don't benar-benar tahu apakah itu's benar. Saya kira pada dasarnya adalah bahwa ketika C pertama kali dikembangkan dan distandarisasi, itu bukan't menyadari betapa pentingnya itu adalah untuk dapat platform-independen mendapatkan integer tipe ukuran tertentu, dan dengan demikian semua asli C tipe integer mungkin ukuran yang berbeda pada platform yang berbeda. Dengan demikian semua orang mencoba untuk menulis portabel kode C harus melakukannya sendiri.

Apakah hal ini benar? Jika demikian, bagaimana apakah programmer diharapkan untuk menggunakan integer C jenis? Maksudku, di tingkat rendah bahasa dengan banyak sedikit memutar-mutar, isn't itu penting untuk dapat mengatakan "ini adalah 32 bit integer"? Dan karena bahasa adalah standar pada tahun 1989, pasti ada beberapa orang yang berpikir bahwa orang akan mencoba untuk menulis portable code?

Mengomentari pertanyaan (18)
Larutan

Ketika C mulai komputer yang kurang homogen, dan banyak kurang terhubung dari hari ini. Itu dilihat sebagai lebih penting untuk portabilitas bahwa tipe int menjadi alami size(s) untuk komputer. Meminta persis 32-bit integer tipe 36-bit sistem ini mungkin akan mengakibatkan tidak efisien kode.

Dan kemudian datanglah meresap jaringan di mana anda bekerja dengan spesifik on-the-wire size bidang. Sekarang interoperabilitas terlihat jauh berbeda. Dan 'oktet' menjadi de facto quanta tipe data.

Sekarang anda perlu int tepat kelipatan dari 8-bit, jadi sekarang anda mendapatkan typedef sup dan kemudian akhirnya standar menangkap dan kami memiliki standar nama mereka dan sup ini tidak diperlukan.

Komentar (18)

C's sebelumnya sukses adalah karena itu flexibility untuk beradaptasi dengan hampir semua ada varian arsitektur @John Hascall dengan:

  1. asli integer ukuran 8, 16, 18, 24, 32, 36, dll. bit,
  2. varian integer ditandatangani model: 2's melengkapi, 1's melengkapi, menandatangani bilangan bulat dan
  3. berbagai endian, besar, kecil dan lain-lain.

Sebagai coding dikembangkan, algoritma dan pertukaran data didorong untuk keseragaman dan sehingga kebutuhan untuk jenis yang memenuhi 1 & 2 di atas seluruh platform. Coders digulung mereka sendiri seperti typedef int int32 dalam #jika .... Banyak variasi yang dibuat sup seperti dicatat oleh OP.


C99 diperkenalkan (u)int_leastN_t, (u)int_fastN_t, (u)intmax_t untuk membuat portable namun somewhat minimum bit-lebar-an jenis. Jenis ini diperlukan untuk N = 8,16,32,64.

Juga diperkenalkan adalah semi-optional jenis (lihat di bawah **) seperti (u)intN_t yang memiliki atribut tambahan dari mereka harus 2's melengkapi dan tidak ada padding. Ini adalah jenis populer yang begitu luas yang diinginkan dan digunakan untuk menipis integer soup.


bagaimana programmer diharapkan untuk menggunakan integer C jenis?

Dengan menulis kode fleksibel yang tidak sangat bergantung pada bit lebar. Ini cukup mudah untuk kode strtol() menggunakan LONG_MIN, LONG_MAX tanpa memperhatikan bit-lebar/endian/integer encoding.

Namun banyak coding tugas-tugas yang mewajibkan tepat jenis lebar dan 2's pelengkap untuk memudahkan kinerja tinggi coding. Hal ini lebih baik dalam hal ini untuk mengorbankan portabilitas 36-bit mesin dan 32-bit tanda-besaran dan tongkat dengan 2N lebar (2's pelengkap untuk ditandatangani) bilangan bulat. Berbagai CRC & algoritma kripto dan format file yang datang ke pikiran. Dengan demikian perlu untuk fixed-width dan jenis tertentu (C99) cara untuk melakukan itu.


Hari ini masih ada gotchas yang masih perlu dikelola. Contoh: biasa promosi int/unsigned kehilangan kontrol seperti jenis-jenis mungkin 16, 32 atau 64.


**

jenis Ini adalah opsional. Namun, jika penerapan menyediakan tipe integer dengan lebar 8, 16, 32, atau 64 bit, tidak ada padding bits, dan (untuk ditandatangani jenis) yang memiliki komplemen dua representasi, itu akan menentukan sesuai typedef nama. C11 7.20.1.1 Tepat-lebar integer tipe 3

Komentar (2)

Saya ingat waktu itu saya'm bersalah melakukan hal yang sama!

Salah satu masalah adalah ukuran dari int, itu bisa menjadi sama seperti pendek, atau lama atau di antara. Misalnya, jika anda bekerja dengan format file biner, itu adalah penting bahwa segala sesuatu yang menyelaraskan. Byte ordering hal-hal yang rumit juga. Banyak pengembang pergi malas rute dan hanya melakukan fwrite dari apa pun, bukannya memetik angka dengan byte-by-byte. Ketika mesin ditingkatkan untuk panjang kata lagi, semua neraka melanggar longgar. Jadi typedef itu mudah hack untuk memperbaiki kesalahan itu.

Jika kinerja adalah sebuah masalah, karena sering kembali kemudian, int dijamin untuk menjadi mesin's alami tercepat ukuran, tetapi jika anda memerlukan 32 bit, dan int lebih pendek dari itu, anda berada dalam bahaya rollover.

Dalam bahasa C, sizeof() adalah tidak seharusnya diselesaikan pada tahap preprocessor, yang membuat hal-hal rumit karena anda tidak't melakukan #jika sizeof(int) == 4 misalnya.

Secara pribadi, beberapa alasan itu juga hanya bekerja dari bahasa assembler pola pikir dan tidak bersedia untuk abstrak keluar gagasan tentang apa yang pendek, int dan panjang untuk. Kembali kemudian, assembler digunakan dalam C cukup sering.

Saat ini, ada banyak non-biner format file, JSON, XML, dll. di mana itu doesn't peduli apa representasi biner adalah. Juga, banyak platform populer telah menetap di 32-bit int atau lebih, yang biasanya cukup untuk sebagian besar tujuan, sehingga ada's kurang dari masalah dengan rollover.

Komentar (5)

C adalah produk dari awal tahun 1970-an, ketika ekosistem komputasi sangat berbeda. Bukan dari jutaan komputer yang semua berbicara satu sama lain melalui jaringan, anda mungkin seratus ribu sistem di seluruh dunia, masing-masing berjalan beberapa monolitik aplikasi, dengan hampir tidak ada komunikasi antara sistem. Anda tidak't asumsikan bahwa ada dua arsitektur memiliki kata yang sama ukuran, atau diwakili ditandatangani bilangan bulat dengan cara yang sama. Pasar masih cukup kecil yang ada't setiap percieved perlu standarisasi, komputer didn't berbicara satu sama lain (banyak), dan tak seorang pun meskipun banyak tentang portabilitas.

Jika demikian, bagaimana programmer diharapkan untuk menggunakan integer C jenis?

Jika anda ingin menulis secara maksimal portabel kode, maka anda didn't mengasumsikan apa pun di luar apa yang Standar dijamin. Dalam kasus int, yang berarti anda tidak't mengasumsikan bahwa hal itu bisa mewakili apa pun di luar jangkauan [-32767,32767], atau apakah anda menganggap bahwa itu akan diwakili dalam 2's pelengkap, atau apakah anda menganggap bahwa itu adalah lebar tertentu (bisa lebih lebar dari 16 bit, namun masih hanya mewakili 16 bit range jika terdapat padding bits).

Jika anda didn't peduli tentang portabilitas, atau anda melakukan hal-hal yang inheren non-portabel (yang sedikit memutar-mutar biasanya), maka anda digunakan apapun jenis(s) bertemu dengan kebutuhan anda.

Saya melakukan sebagian besar tingkat tinggi aplikasi pemrograman, jadi saya sedikit khawatir tentang representasi dari saya tentang berbagai. Meski begitu, saya kadang-kadang diperlukan untuk mencelupkan ke dalam representasi biner, dan itu selalu sedikit saya di pantat. Aku ingat menulis beberapa kode di awal '90-an yang harus dijalankan pada klasik MacOS, Windows 3.1, dan Solaris. Aku dibuat sekelompok konstanta enumerasi untuk 32-bit masker, yang bekerja dengan baik pada Mac dan Unix kotak, tapi gagal untuk mengkompilasi pada Windows box karena pada Windows yang int hanya 16 bit lebar.

Komentar (1)

C dirancang sebagai bahasa yang bisa porting ke berbagai mesin sebagai tamu, bukan sebagai bahasa yang akan memungkinkan sebagian besar jenis program yang akan berjalan tanpa modifikasi pada berbagai mesin. Untuk sebagian besar tujuan praktis, C's jenis:

  • 8-bit jenis jika tersedia, atau yang lain type terkecil yang's setidaknya 8 bit.

  • 16-bit jenis, jika tersedia, atau yang lain type terkecil yang's setidaknya 16 bit.

  • 32-bit jenis, jika tersedia, atau yang lain beberapa jenis yang's setidaknya 32 bit.

  • Jenis yang akan menjadi 32 bit jika sistem yang dapat menangani hal-hal seperti seefisien 16-bit jenis, atau 16 bit sebaliknya.

Jika kode yang dibutuhkan 8, 16, atau 32-bit jenis dan akan tidak mungkin untuk dapat digunakan pada mesin yang tidak mendukung mereka, tidak ada hal yang't setiap masalah yang tertentu dengan kode tersebut mengenai char, pendek, dan panjang 8, 16, dan 32 bit, masing-masing. Satu-satunya sistem yang tidak't peta nama-nama tersebut untuk jenis-jenis yang akan menjadi orang-orang yang tidak't mendukung jenis-jenis dan tidak't dapat berguna menangani kode yang diperlukan mereka. Sistem seperti ini akan terbatas untuk menulis kode yang telah ditulis untuk menjadi kompatibel dengan jenis yang mereka gunakan.

Saya pikir C bisa mungkin terbaik dilihat sebagai resep untuk mengkonversi spesifikasi sistem ke bahasa dialek. Sebuah sistem yang menggunakan 36-bit memori won't benar-benar dapat secara efisien proses yang sama dialek bahasa sebagai suatu sistem yang menggunakan oktet berbasis memori, tetapi seorang programmer yang belajar satu dialek akan mampu belajar lain hanya dengan belajar apa integer representasi yang terakhir yang menggunakan. It's jauh lebih berguna untuk memberitahu seorang programmer yang membutuhkan untuk menulis kode untuk 36-bit sistem, "mesin Ini sama seperti mesin lain kecuali char adalah 9 bit, pendek adalah 18 bit, dan panjang adalah 36 bit", daripada mengatakan "Anda harus menggunakan bahasa assembly karena bahasa-bahasa lain akan memerlukan tipe integer sistem ini dapat't proses yang efisien".

Komentar (4)

Tidak semua mesin yang sama dengan kata asli ukuran. Meskipun anda mungkin tergoda untuk berpikir yang lebih kecil ukuran variabel akan lebih efisien, itu hanya ain't jadi. Bahkan, dengan menggunakan variabel yang sama dengan ukuran asli kata ukuran CPU yang jauh, jauh lebih cepat untuk aritmatika, logika dan manipulasi bit operasi.

Tapi apa, tepatnya, adalah "kata asli ukuran"? Hampir selalu, ini berarti ukuran register CPU, yang adalah sama dengan Arithmetic Logic Unit (ALU) dapat bekerja dengan.

Dalam tertanam lingkungan, masih ada hal-hal seperti itu sebagai 8 dan 16 bit Cpu (masih ada 4-bit PIC controller?). Ada pegunungan prosesor 32-bit di luar sana masih. Jadi konsep "kata asli ukuran" masih hidup dan baik untuk C pengembang.

Dengan prosesor 64-bit, sering ada dukungan yang baik untuk 32-bit operand. Dalam praktek, menggunakan 32-bit integer dan floating point nilai-nilai yang sering bisa lebih cepat dari kata penuh ukuran.

Juga, ada trade-off antara penduduk asli kata keselarasan dan memori secara keseluruhan konsumsi ketika meletakkan C struktur.

Tapi dua pola penggunaan umum tetap: ukuran agnostik kode untuk meningkatkan kecepatan (int, short, long), atau ukuran yang tetap (int32_t, int16_t, int64_t) untuk kebenaran atau interoperabilitas di mana diperlukan.

Komentar (11)