Kode saya:
#include <stdio.h>
#include <limits.h>
int main()
{
char c = CHAR_MAX;
c += 1;
printf("CHAR_MIN=%d CHAR_MAX=%d c=%d (%c)\n", CHAR_MIN, CHAR_MAX, c, c);
}
Keluaran:
CHAR_MIN=-128 CHAR_MAX=127 c=-128 ()
Kita melihat bahwa ketika kita menambah char
set variabel ke CHAR_MAX
, itu membungkus sekitar CHAR_MIN
. Apakah perilaku ini dijamin? Atau apakah itu akan menjadi perilaku yang tidak terdefinisi atau perilaku yang ditentukan implementasi? Apa yang dikatakan standar C99 tentang ini?
[Catatan: Apa yang terjadi ketika memberi nilai lebih besar dari CHAR_MAX (127) ke char atau C- mengapa char c = 129 akan dikonversi menjadi -127? tidak menjawab pertanyaan ini karena mereka berbicara tentang menetapkan nilai out-of-range tidak menambah nilai ke nilai out-of-range.]
c
char
language-lawyer
standards
integer-overflow
Lone Learner
sumber
sumber
Jawaban:
Pertanyaannya ada dua: Pertama
dievaluasi berbeda dari
dan jawabannya adalah tidak , karena C11 / C18 6.5.16.2p3 :
Lalu, pertanyaannya adalah apa yang terjadi di
c = c + 1
. Di sini operan untuk+
menjalani konversi aritmatika biasa, danc
dan1
karenanya dipromosikanint
, kecuali jika arsitektur yang benar-benar aneh mengharuskan yangchar
dipromosikanunsigned int
. Perhitungan+
kemudian dievaluasi, dan hasilnya, jenisint
/unsigned int
dikonversi kembali kechar
dan disimpan dalamc
.Ada 3 cara yang ditentukan implementasi yang kemudian dapat dievaluasi:
CHAR_MIN
adalah 0 dan karenanyachar
tidak ditandatangani.Entah
char
kemudian dipromosikan keint
atauunsigned int
dan jika dipromosikan keint
, makaCHAR_MAX + 1
tentu akan cocok menjadiint
terlalu, dan tidak akan meluap, atau jikaunsigned int
mungkin cocok atau membungkus ke nol. Ketika nilai yang dihasilkan, yang secara numerik baikCHAR_MAX + 1
atau0
setelah pengurangan modulo, kembali kec
, setelah pengurangan modulo itu akan menjadi 0, yaituCHAR_MIN
Jika
char
tidak ditandatangani, maka jikaCHAR_MAX
lebih kecil dariINT_MAX
, hasilCHAR_MAX + 1
akan cocokint
, dan standar C11 / C18 6.3.1.3p3 berlaku untuk konversi yang terjadi pada penugasan :Atau, jikaf
sizeof (int) == 1
danchar
ditandatangani, makachar
dipromosikan keint
, danCHAR_MAX == INT_MAX
=>CHAR_MAX + 1
akan menyebabkan bilangan bulat bilangan bulat dan perilaku akan tidak terdefinisi .Yaitu hasil yang mungkin adalah:
Jika
char
adalah tipe integer yang tidak ditandatangani, hasilnya selalu0
, yaituCHAR_MIN
.Jika tidak,
char
merupakan tipe integer yang ditandatangani, dan perilaku didefinisikan-didefinisikan / tidak didefinisikan:CHAR_MIN
atau beberapa nilai yang ditentukan implementasi lainnya,sizeof (char) == sizeof (int)
.Semua operasi increment
c = c + 1
,c += 1
,c++
dan++c
memiliki efek samping yang sama pada platform yang sama. Nilai ekspresi yang dievaluasic++
akan menjadi nilaic
sebelum kenaikan; untuk tiga lainnya, itu akan menjadi nilaic
setelah kenaikan.sumber
sizeof(int) == 1
akan membutuhkanCHAR_BITS >= 16
, kan?<pedantic>
IDK tentangCHAR_BITS
tetapiCHAR_BIT
akan>= 16</pedantic>
.char
harus selalu tidak ditandatangani secara default.