Mengapa unsigned int dari bit-field menjadi int bertanda tangan setelah operasi shift di C ++? [duplikat]
Kode tes:
struct A
{
uint32_t lo : 16;
uint32_t hi : 16;
};
int main()
{
A a{};
a.lo = 0xFFFF;
auto b = a.lo << 16;
cout << b << endl;
return 0;
}
Outputnya adalah:, -65536
dan jenisnya b
adalah int
tetapi tidak uint32_t
.
Saya telah menemukan itu, uint16_t
dan uint8_t
juga akan menjadi ditandatangani int setelah operator shift, dan ada pertanyaan serupa di C#
, yang sampai pada kesimpulan bahwa hasilnya akan menjadi ditandatangani ketika operan <32 bit. Mengapa operasi shift selalu menghasilkan int yang ditandatangani ketika operan <32 bit
Tapi jenisnya a.lo
jelas uint32_t
, yang bisa dibuktikan kebenarannya decltype(a.lo)
, lalu bagaimana menjelaskannya?
Jawaban
Itu bagian dari promosi integral standar.
[expr.shift]
1 Operator shift
<<
dan>>
grup dari kiri ke kananOperand harus dari tipe enumerasi integral atau tanpa cakupan dan promosi integral dilakukan. Jenis hasilnya adalah operan kiri yang dipromosikan.
[konv.prom]
5 Sebuah prvalue untuk integral bit-field ([class.bit]) dapat diubah menjadi prvalue tipe
int
jikaint
dapat mewakili semua nilai dari bit-field; jika tidak, dapat diubah menjadiunsigned int
jikaunsigned int
dapat mewakili semua nilai bidang bit. Jika bit-field lebih besar lagi, tidak ada promosi integral yang berlaku untuk itu. Jika bit-field memiliki tipe yang disebutkan, itu diperlakukan sebagai nilai lain dari tipe itu untuk tujuan promosi.
Promosi operan kiri Anda (bit-field) menghasilkan int
, dan itulah jenis ekspresi keseluruhan shift. Dengan demikian b
adalah int
juga dengan jenis placeholder deduksi.