1-bit signed int 只剩符號位了,能用來幹啥?Bit-field 用 unsigned int 是常識吧。

===============編譯環境:VS2013,Win8.1==============

先看內存布局

位域的聲明需要標識數據類型,例int b : 2、char b : 2等。故位域的內存布局和對齊影響應該與替換成該類型對應的成員時(即將int b : 2替換成int b時)一樣,不再贅述。

上代碼:

看結果(與上述相符):再來看內存中位域數據的擺放位置存取方式: 見下面兩張圖(第二章中白色為C++代碼,灰色為彙編代碼)每個對位域的賦值都可以對應到一條關鍵的or彙編代碼,第一個位域賦值直接將word大小的數據or常量3,第二個先將統一數據的低3-5位置零(and 常數0FFE3H),然後or常量10H。由此可見,位域的擺放從內存的低位到高位, 並會合理的利用空餘內存存放數據,畢竟位域就是為這個而生的。同時從上圖中可見,位域的,是通過掩碼運算實現的。而位域的,從下圖可見,是通過位移實現的


就是普通變數,多個挨著的位域會合併,大端小端不一定。占的空間看這個問題一個C++題目,這個sizeof輸出是多少呢? - 劉佩奇的回答

重新修改一下,測試環境win,vs2015.

先說結論,同類型挨著的位域才會合併,不挨著的當普通變數,挨著的位域大小超了一個類型的大小,則分開放兩個變數里。對齊規則同上面貼的鏈接,64bit也是。

struct A {
char c : 1;
int i : 1;
short s : 1;
long long ll : 1;
};
A a;
a.c =0;
a.i =0;
a.s =0;
a.ll=0;
cout &

反彙編

/*32 bit
A a;
a.c =0;
00141CCD mov al,byte ptr [a]
00141CD0 and al,0FEh
00141CD2 mov byte ptr [a],al
a.i =0;
00141CD5 mov eax,dword ptr [ebp-1Ch]
00141CD8 and eax,0FFFFFFFEh
00141CDB mov dword ptr [ebp-1Ch],eax
a.s =0;
00141CDE mov ax,word ptr [ebp-18h]
00141CE2 and ax,0FFFEh
00141CE6 mov word ptr [ebp-18h],ax
a.ll=0;
00141CEA mov eax,dword ptr [ebp-10h]
00141CED and eax,0FFFFFFFEh
00141CF0 mov ecx,dword ptr [ebp-0Ch]
00141CF3 mov dword ptr [ebp-10h],eax
00141CF6 mov dword ptr [ebp-0Ch],ecx
B b;
b.c1 = 0;
00EB5A90 mov al,byte ptr [b]
00EB5A93 and al,80h
00EB5A95 mov byte ptr [b],al
b.c2 = 0;
00EB5A98 mov al,byte ptr [ebp-37h]
00EB5A9B and al,0FCh
00EB5A9D mov byte ptr [ebp-37h],al
b.i1 = 0;
00EB5AA0 mov eax,dword ptr [ebp-34h]
00EB5AA3 and eax,0FFFFFFF0h
00EB5AA6 mov dword ptr [ebp-34h],eax
b.i2 = 0;
00EB5AA9 mov eax,dword ptr [ebp-34h]
00EB5AAC and eax,0FFFFFFEFh
00EB5AAF mov dword ptr [ebp-34h],eax
b.l = 0;
00EB5AB2 mov eax,dword ptr [ebp-30h]
00EB5AB5 and eax,0FFFFFFFEh
00EB5AB8 mov ecx,dword ptr [ebp-2Ch]
00EB5ABB mov dword ptr [ebp-30h],eax
00EB5ABE mov dword ptr [ebp-2Ch],ecx
*/

debug模式,沒有開優化,A是24位元組,B是16位元組,彙編ebp的增減直接體現了具體每一個的地址關係與大小。

想起來之前不知道哪裡看到的:

其實不用太考慮位元組對齊,寫struct(class),把空間大的變數放前邊,空間小的放後邊,能節省一點.

又,不相信書就敲一遍。


前幾天剛整理了一下 http://www.dpull.com/blog/2016-07-24-bit_fields_cross_platform

剛好最近研究了這塊兒的內容,以VC編譯器為例,總結了C/C++位域結構深入解析 - Jocent Zhou 這篇文章,應該能夠完美解決該問題


位元組對齊與普通struct並沒有區別。位域的話,確實不同的編譯器有不同的實現,但無非就兩種:bit0在最低位或者bit0在最高位。

比如:union{ unsigned Int v; struct { bit0:1;

bit1:1;

bit2:1; bit3:1; ... bit31:1; }bits;}u;u.v=0; //bit0~bit31都是0u.bits.bit0 = 1; //u.v可能的取值有兩種,0x80000000或者0x1,這個就和編譯器實現有關了,有些編譯器可以增加編譯參數來確定位域的bit分布。對於bit0為低位:其實你讀取u.bits.bit(n)的時候,就相當於(u.v&>&>n)1,寫u.bits.bit(n),相當於u.v = u.v(~(1&
我記得《The C Programming Language》裡面提到過,位域的那個【位】究竟是位於當前位元組的【低位】還是【高位】,屬於編譯器實現相關,不是固定的。即不確定是:

bxxxxxxx

還是:xxxxxxxb
推薦閱讀:
相关文章