Saya menggunakan int unsigned untuk membuat kode dan maksud saya lebih jelas. Satu hal yang saya lakukan untuk menjaga terhadap konversi tersirat yang tidak terduga ketika melakukan aritmatika dengan kedua tipe bertanda tangan dan tidak bertanda adalah menggunakan short unsigned (biasanya 2 byte) untuk variabel unsigned saya. Ini efektif karena beberapa alasan:
- Ketika Anda melakukan aritmatika dengan variabel pendek yang tidak ditandatangani dan literal (yang bertipe int) atau variabel bertipe int, ini memastikan variabel yang tidak ditandatangani akan selalu dipromosikan ke int sebelum mengevaluasi ekspresi, karena int selalu memiliki peringkat lebih tinggi daripada pendek. . Ini menghindari perilaku tak terduga yang melakukan aritmatika dengan tipe bertanda tangan dan tidak bertanda, dengan asumsi hasil dari ekspresi cocok dengan int yang sudah ditandatangani tentunya.
- Sebagian besar waktu, variabel unsigned yang Anda gunakan tidak akan melebihi nilai maks dari 2-byte pendek unsigned (65.535)
Prinsip umum adalah bahwa jenis variabel tidak bertanda tangan Anda harus memiliki peringkat lebih rendah dari jenis variabel yang ditandatangani untuk memastikan promosi ke jenis yang ditandatangani. Maka Anda tidak akan memiliki perilaku luapan yang tidak terduga. Jelas Anda tidak bisa memastikan ini setiap saat, tetapi (kebanyakan) seringkali layak untuk memastikan hal ini.
Sebagai contoh, baru-baru ini saya memiliki sesuatu untuk loop seperti ini:
const unsigned short cuint = 5;
for(unsigned short i=0; i<10; ++i)
{
if((i-2)%cuint == 0)
{
//Do something
}
}
Huruf '2' adalah tipe int. Jika saya adalah unsigned int bukannya short unsigned, maka dalam sub-ekspresi (i-2), 2 akan dipromosikan menjadi int unsigned (karena int unsigned memiliki prioritas lebih tinggi daripada int yang ditandatangani). Jika i = 0, maka sub-ekspresi sama dengan (0u-2u) = beberapa nilai besar karena melimpah. Gagasan yang sama dengan i = 1. Namun, karena saya adalah kependekan dari unsigned, maka dipromosikan ke jenis yang sama dengan literal '2', yang ditandatangani int, dan semuanya berfungsi dengan baik.
Untuk keamanan tambahan: dalam kasus yang jarang di mana arsitektur yang Anda laksanakan pada penyebab int menjadi 2 byte, ini dapat menyebabkan kedua operan dalam ekspresi aritmatika dipromosikan menjadi int tidak bertanda dalam kasus di mana variabel pendek yang tidak ditandai tidak cocok ke dalam int 2-byte yang ditandatangani, yang terakhir memiliki nilai maksimum 32.767 <65.535. (Lihat https://stackoverflow.com/questions/17832815/c-implicit-conversion-signed-unsigned untuk lebih jelasnya). Untuk mencegah hal ini, Anda cukup menambahkan static_assert ke program Anda sebagai berikut:
static_assert(sizeof(int) == 4, "int must be 4 bytes");
dan itu tidak akan dikompilasi pada arsitektur di mana int adalah 2 byte.
for(unsigned int n = 10; n >= 0; n --)
(loop tak terhingga)