Mengapa semua orang mengetik lebih dari tipe C standar?

103

Jika Anda ingin menggunakan Qt , Anda harus merangkul quint8, quint16dan lain sebagainya.

Kalau mau pakai GLib harus diterima guint8, guint16dan lain sebagainya.

Di Linux ada u32, s16dan lain sebagainya.

Definisi UC / OSSINT32 , UINT16dan sebagainya.

Dan jika Anda harus menggunakan beberapa kombinasi dari hal-hal itu, lebih baik Anda bersiap untuk masalah. Karena pada mesin Anda u32akan typedefselesai longdan quint32akan typedefselesai intdan compiler akan mengeluh .

Mengapa setiap orang melakukan ini, jika ada <stdint.h>? Apakah ini semacam tradisi untuk perpustakaan?

Amomum
sumber
8
@Mehrdad dalam pemrograman mikrokontroler Anda dapat memiliki segala macam hal. Pada AVR Mega misalnya (dan akibatnya pada Arduino yang terkenal) int adalah 16 bit. Itu mungkin kejutan yang buruk. Menurut saya, 'unsigned short' membutuhkan lebih banyak tenaga pengetikan. Dan itu selalu membuat saya sedih menggunakan 'unsigned char' untuk oktet <s> byte </s>. Karakter unsigned, benarkah?
Amomum
2
@Mehrdad Intinya adalah Anda tidak bisa benar-benar yakin. Itulah mengapa stdint.hditemukan.
glglgl
1
@glglgl: Berikut cara lain untuk melihat masalah: bukankah Anda menanyakan pertanyaan yang salah? Jika Anda menargetkan beberapa sistem, mengapa secara acak membuat kode keras jumlah bit ke dalam kode di tempat pertama? yaitu, mengapa tidak mengatakan sizeof(int) * CHAR_BIT(misalnya) dan menggunakan itu? Jika Anda intterlalu kecil untuk mewakili rentang Anda (misalnya indeks array), maka Anda hampir pasti tidak boleh menggunakannya int, tetapi sesuatu seperti size_t. Mengapa int32lebih masuk akal? Satu-satunya waktu dengan lebar tetap yang masuk akal adalah untuk komunikasi antar sistem (misalnya format file / jaringan) ...
pengguna541686
1
@Mehrdad Tidak. Terkadang saya memiliki nilai (seperti dari ADC atau apa pun) yang perlu saya simpan. Saya tahu lebarnya 16 bit. Jadi cara terbaik untuk digunakan adalah uint16_t(atau mungkin fastatau leastvariannya). Maksud saya adalah: Jenis ini nyaman digunakan dan memiliki alasan keberadaannya.
glglgl
1
@Mehrdad: Saya menyarankan bahwa - dengan asumsi tampaknya upaya Anda untuk menghasilkan kode kualitas - Anda harus menentukan typedef fungsional Anda sendiri yang berarti cara berinteraksi dengan API saya / sisa kode saya , dan mendefinisikannya atas dasar teknis dalam hal Typedef "teknis" seperti size_tdan / atau uint64_t.
PJTraill

Jawaban:

80

stdint.htidak ada kembali saat perpustakaan ini dikembangkan. Jadi setiap perpustakaan membuat sendiri typedef.

Edward Karak
sumber
4
Dan oke, saya kira kurangnya stdint.h adalah alasan yang bagus, tapi mengapa bahkan hari ini typedefs ini lebih dari int, long dan untuk dan bukan stdint? Itu akan membuat mereka dapat dipertukarkan setidaknya
Amomum
25
@Amomum "Mengapa Glib (yang dikembangkan di Linux) tidak menggunakan Linux typedefs?" Sementara "home base" dari glib adalah Linux, itu juga dengan desain perpustakaan portabel. Mendefinisikan tipenya sendiri memastikan portabilitas: Seseorang hanya perlu mengadaptasi sebuah header kecil yang cocok dengan tipe library dengan tipe platform target yang sesuai.
Peter - Kembalikan Monica
3
@Amomum Why Glib (yang dikembangkan di Linux) ... Tidak, ternyata tidak. Glib dibuat jauh sebelum kernel Linux.
andy256
5
@ andy256 "GLib" bukan singkatan dari "glibc". Ini adalah perpustakaan yang bercabang dari gtk. Ini tidak lebih tua dari Linux.
2
@ andy256: glib 1998, linux 1991. IOW, GLib dibuat jauh setelah Linux.
MSalters
40

Untuk pustaka yang lebih lama, ini diperlukan karena header yang dimaksud ( stdint.h) tidak ada.

Namun, masih ada masalah di sekitar: tipe tersebut ( uint64_tdan lainnya) adalah fitur opsional dalam standar. Jadi implementasi yang sesuai mungkin tidak disertakan bersama mereka - dan dengan demikian memaksa perpustakaan untuk tetap menyertakannya saat ini.

Ven
sumber
14
The uintN_tjenis adalah opsional, tetapi uint_leastN_tdan uint_fastN_tjenis tidak.
Kusalananda
7
@Kusalananda: Sayangnya kegunaannya terbatas.
Balapan Ringan di Orbit
16
Tentu saja alasan bahwa mereka adalah opsional adalah bahwa Anda tidak dijamin bahwa ada yang bulat jenis dengan tepat jumlah bit. C masih mendukung arsitektur dengan ukuran bilangan bulat yang agak aneh.
celtschk
5
@LightnessRacesinOrbit: Bagaimana kegunaannya yang terbatas? Saya harus mengakui bahwa terlepas dari antarmuka perangkat keras, saya tidak mengerti mengapa Anda memerlukan jumlah bit yang tepat, bukan hanya minimum, untuk memastikan semua nilai Anda sesuai.
celtschk
23
@Amomum The typedef yang diperlukan jika pelaksanaan memiliki jenis yang memenuhi persyaratan: "Namun, jika sebuah implementasi menyediakan bilangan bulat jenis dengan lebar 8, 16, 32, atau 64 bit, ada padding bit, dan (untuk tipe ditandatangani) yang memiliki representasi komplemen dua, itu akan mendefinisikan nama typedef yang sesuai. " (kutipan dari N1570, 7.20.1.1 "Exact-width integer types") Jadi, jika pustaka standar tidak memilikinya, pustaka pihak ketiga tampaknya juga tidak bisa.
Eric M Schmidt
13

stdint.h telah distandarisasi sejak 1999. Tampaknya banyak aplikasi yang mendefinisikan (alias secara efektif) jenis untuk mempertahankan independensi parsial dari arsitektur mesin yang mendasarinya.

Mereka memberikan keyakinan kepada pengembang bahwa tipe yang digunakan dalam aplikasi mereka cocok dengan asumsi spesifik proyek mereka pada perilaku yang mungkin tidak cocok dengan standar bahasa atau implementasi compiler.

Praktik ini dicerminkan dalam pola desain Façade berorientasi objek dan banyak disalahgunakan oleh pengembang yang selalu menulis kelas pembungkus untuk semua perpustakaan yang diimpor.

Ketika compliers jauh lebih sedikit standarnya dan arsitektur mesin dapat bervariasi dari 16-bit, 18-bit hingga 36-bit word length mainframe, ini lebih menjadi pertimbangan. Praktik ini jauh lebih tidak relevan sekarang di dunia yang berkumpul pada sistem tertanam ARM 32-bit. Ini tetap menjadi perhatian bagi mikrokontroler kelas bawah dengan peta memori yang aneh .

Pekka
sumber
1
Memang, stdint.htelah distandarisasi sejak 1999, tetapi sudah berapa lama dalam praktiknya? Orang-orang berlarut-larut dalam menerapkan dan mengadopsi standar baru, dan selama masa transisi yang panjang itu, metode lama masih merupakan suatu keharusan.
Siyuan Ren
1
Satu masalah buruk dengan stdint.hadalah bahwa bahkan pada platform di mana misalnya longdan int32_tmemiliki ukuran dan representasi yang sama, tidak ada persyaratan bahwa mentransmisikan int32_t*ke long*akan menghasilkan penunjuk yang dapat diandalkan mengakses a int32_t. Saya tidak percaya penulis Standar berpikir dengan jelas bahwa jenis yang kompatibel dengan tata letak harus kompatibel dengan alias, tetapi karena mereka tidak repot-repot mengatakannya sehingga penulis gcc dan IIRC dentang berpikir bahasanya akan ditingkatkan dengan mengabaikan aliasing bahkan dalam kasus di mana sudah jelas.
supercat
2
@supercat - itu mungkin layak untuk diserahkan sebagai erratum ke komite C ... karena itu sangat bodoh , untuk membuatnya lebih ringan
LThode
@LThode: Agar komite C mengakui bahwa sebagai kesalahan akan mengharuskannya secara resmi menyatakan perilaku clang dan gcc sebagai tumpul. Apakah menurut Anda itu akan terjadi? Yang terbaik yang bisa diharapkan (dan IMHO cara logis untuk melanjutkan) adalah dengan menentukan cara program untuk menentukan "mode aliasing". Jika sebuah program mengatakan menetapkan bahwa ia dapat menerima aturan aliasing yang sangat ketat, maka compiler dapat menggunakannya untuk memungkinkan pengoptimalan melebihi apa yang mungkin saat ini dilakukan. Jika sebuah program menetapkan bahwa ia membutuhkan aturan yang agak lebih ramah programmer daripada yang sekarang ...
supercat
... tetapi masih akan memungkinkan banyak pengoptimalan yang berguna, maka kompiler dapat menghasilkan kode yang jauh lebih efisien daripada yang mungkin dilakukan -fno-strict-alias, tetapi yang sebenarnya masih berfungsi. Bahkan jika tidak ada basis kode yang ada, tidak ada satu set aturan yang dapat mencapai keseimbangan optimal pengoptimalan dan semantik untuk semua aplikasi, karena aplikasi yang berbeda memiliki kebutuhan yang berbeda. Tambahkan basis kode yang ada dan kebutuhan akan mode yang berbeda harus jelas.
supercat
3

Jadi Anda memiliki kekuatan untuk mengetikkan char to int.

Satu "koding horor" menyebutkan bahwa salah satu header perusahaan memiliki titik di mana seorang programmer menginginkan nilai boolean, dan karakter adalah tipe asli logis untuk pekerjaan tersebut, dan begitu juga menulis typedef bool char. Kemudian kemudian seseorang menemukan bilangan bulat menjadi pilihan paling logis, dan menulis typedef bool int. Hasilnya, jauh sebelum Unicode, secara virtual typedef char int.

Cukup banyak pemikiran ke depan, kompatibilitas ke depan, menurut saya.

Christos Hayward
sumber