Saya melihat kode di bawah ini di posting Quora ini :
#include <stdio.h>
struct mystruct { int enabled:1; };
int main()
{
struct mystruct s;
s.enabled = 1;
if(s.enabled == 1)
printf("Is enabled\n"); // --> we think this to be printed
else
printf("Is disabled !!\n");
}
Di C & C ++, keluaran kode tidak terduga ,
Dinonaktifkan !!
Meskipun penjelasan terkait "sedikit tanda" diberikan dalam posting itu, saya tidak dapat memahami, bagaimana mungkin kita mengatur sesuatu dan kemudian tidak mencerminkan apa adanya.
Bisakah seseorang memberikan penjelasan yang lebih rinci?
Catatan : Kedua tag tersebutc & c ++diperlukan, karena standarnya sedikit berbeda untuk menggambarkan bidang bit. Lihat jawaban untuk spesifikasi C dan spesifikasi C ++ .
int
menurut saya hanya dapat menampung nilai0
dan-1
.struct mystruct { unsigned int enabled:1; };
?Jawaban:
Bit-field sangat tidak ditentukan oleh standar. Dengan adanya kode ini
struct mystruct {int enabled:1;};
, maka kita tidak tahu:int:n
bitfield akan dianggap sebagai ditandatangani atau tidak.Mengenai bagian terakhir, C17 6.7.2.1/10 mengatakan:
Catatan non-normatif yang menjelaskan di atas:
Dalam hal bitfield akan dianggap sebagai
signed int
dan Anda membuat sedikit ukuran1
, maka tidak ada ruang untuk data, hanya untuk bit tanda. Inilah alasan mengapa program Anda mungkin memberikan hasil yang aneh pada beberapa kompiler.Praktik yang baik:
int
tipe bertanda tangan untuk segala bentuk manipulasi bit.sumber
Apakah Anda bertanya mengapa itu mengkompilasi vs. memberi Anda kesalahan?
Ya, itu idealnya memberi Anda kesalahan. Dan memang demikian, jika Anda menggunakan peringatan kompiler Anda. Di GCC, dengan
-Werror -Wall -pedantic
:Alasan mengapa hal ini dibiarkan menjadi ditentukan oleh implementasi vs. kesalahan mungkin lebih berkaitan dengan penggunaan historis, di mana membutuhkan pemeran berarti melanggar kode lama. Para penulis standar mungkin percaya peringatan sudah cukup untuk mengisi kekosongan bagi mereka yang berkepentingan.
Untuk menambahkan beberapa preskriptiftivisme, saya akan menggemakan pernyataan @ Lundin: "Jangan pernah menggunakan bidang bit untuk tujuan apa pun." Jika Anda memiliki jenis alasan yang baik untuk mendapatkan tingkat rendah dan spesifik tentang detail tata letak memori Anda yang akan membuat Anda berpikir bahwa Anda membutuhkan bitfields, persyaratan terkait lainnya yang hampir pasti Anda miliki akan berjalan berlawanan dengan spesifikasi yang terlalu rendah.
(TL; DR - Jika Anda cukup canggih untuk secara sah "membutuhkan" bidang bit, mereka tidak cukup terdefinisi dengan baik untuk melayani Anda.)
sumber
char
, dukungan untuk byte yang bukan 8 bit, dll. Mereka tidak diizinkan untuk memberikan komputer tolol kerugian pasar.Ini adalah implementasi perilaku yang ditentukan. Saya membuat asumsi bahwa mesin yang Anda jalankan ini menggunakan bilangan bulat bertanda dua-pujian dan memperlakukan
int
dalam kasus ini sebagai bilangan bulat bertanda untuk menjelaskan mengapa Anda tidak memasukkan if true bagian dari pernyataan if.mendeklarasikan
enable
sebagai bidang bit 1 bit. Sejak ditandatangani, nilai yang valid adalah-1
dan0
. Mengatur bidang untuk1
meluap sedikit kembali ke-1
(ini adalah perilaku yang tidak ditentukan)Pada dasarnya ketika berhadapan dengan bit-field yang ditandatangani, nilai maks adalah
2^(bits - 1) - 1
yang0
dalam kasus ini.sumber
-
dan+
. Pelengkap 2 tidak masalah.int
seperti yang ditandatangani dalam kasus ini. Sangat disayangkan bahwa bit-field kurang ditentukan. Pada dasarnya di sini adalah fitur ini, konsultasikan dengan kompiler Anda tentang cara menggunakannya.Anda dapat menganggapnya sebagai bahwa dalam sistem pelengkap 2, bit paling kiri adalah bit tanda. Dengan demikian, bilangan bulat bertanda apa pun dengan kumpulan bit paling kiri adalah nilai negatif.
Jika Anda memiliki bilangan bulat bertanda 1-bit, ia hanya memiliki sedikit tanda. Jadi menugaskan
1
ke bit tunggal itu hanya dapat mengatur bit tanda. Jadi, ketika membacanya kembali, nilainya diartikan sebagai negatif dan begitu juga -1.Nilai yang dapat dimiliki oleh integer bertanda tangan 1 bit adalah
-2^(n-1)= -2^(1-1)= -2^0= -1
dan2^n-1= 2^1-1=0
sumber
Sesuai standar C ++ n4713 , cuplikan kode yang sangat mirip disediakan. Jenis yang digunakan adalah
BOOL
(khusus), tetapi dapat diterapkan ke jenis apa pun.Pada pandangan pertama, bagian tebal tampak terbuka untuk interpretasi. Namun, maksud yang benar menjadi jelas saat
enum BOOL
diturunkan dariint
.Dengan kode di atas memberikan peringatan tanpa
-Wall -pedantic
:Outputnya adalah:
Jika
enum BOOL : int
dibuat sederhanaenum BOOL
, maka outputnya seperti yang ditentukan pasage standar di atas:Oleh karena itu, dapat disimpulkan, seperti beberapa jawaban lain yang dimiliki,
int
tipe tersebut tidak cukup besar untuk menyimpan nilai "1" hanya dalam satu bit-field.sumber
Tidak ada yang salah dengan pemahaman Anda tentang bitfield yang bisa saya lihat. Apa yang saya lihat adalah Anda mendefinisikan ulang mystruct terlebih dahulu sebagai struct mystruct {int enabled: 1; } dan kemudian sebagai struct mystruct s; . Apa yang seharusnya Anda kodekan adalah:
sumber