unsigned char strUserName[MAX_LEN + 1] __PACK__; unsigned int unDHCPMode __PACK__;之前都沒有特別留意,反正別人怎麼宣告,自己也跟著寫就對了;直到最近才想到,於是就上網Google一下,把自己所理解的,記錄下來。
那__PACK__到底是什麼??假如在你的開發環境中搜尋這個字串,相信應該不難找到會在某個檔案裡出現這一行:
#define __PACK__ __attribute__ ((packed))當我們去宣告一個變數的時後,會用掉多少記憶體,通常會去用sizeof()來去計算;但Compiler為了效能考量,會自動地幫我們的程式碼做最佳化的運算,換句話說─就是會偷偷幫我們多準備一些記憶體空間。
請看以下的簡單範例:
// OS: Linux Red Hat 9 // File Name: Main.c #include <stdio.h> int main(void) { int nTemp = 0; short int snTemp = 0; long lnTemp = 0L; float fTemp = 0; char cTemp = '\0'; long long lnlnTemp = 0LL; double dTemp = 0; printf("1. sizeof(int) = %d, sizeof(nTemp) = %d \n", sizeof(int), sizeof(nTemp)); printf("2. sizeof(short int) = %d, sizeof(snTemp) = %d \n", sizeof(short int), sizeof(snTemp)); printf("3. sizeof(long) = %d, sizeof(lnTemp) = %d \n", sizeof(long), sizeof(lnTemp)); printf("4. sizeof(float) = %d, sizeof(fTemp) = %d \n", sizeof(float), sizeof(fTemp)); printf("5. sizeof(char) = %d, sizeof(cTemp) = %d \n", sizeof(char), sizeof(cTemp)); printf("6. sizeof(long long) = %d, sizeof(lnlnTemp) = %d \n", sizeof(long long), sizeof(lnlnTemp)); printf("7. sizeof(double) = %d, sizeof(dTemp) = %d \n", sizeof(double), sizeof(dTemp)); return 0; }gcc ./Main.c -o Main; ./Main
會得到以下的結果:
1. sizeof(int) = 4, sizeof(nTemp) = 4
2. sizeof(short int) = 2, sizeof(snTemp) = 2
3. sizeof(long) = 4, sizeof(lnTemp) = 4
4. sizeof(float) = 4, sizeof(fTemp) = 4
5. sizeof(char) = 1, sizeof(cTemp) = 1
6. sizeof(long long) = 8, sizeof(lnlnTemp) = 8
7. sizeof(double) = 8, sizeof(dTemp) = 8
OK!!那我們現在把程式碼改成用結構 (struct)的方式來呈現:
#include <stdio.h> struct DATA_T { int nTemp; short int snTemp; long lnTemp; float fTemp; char cTemp; long long lnlnTemp; double dTemp; }; int main(void) { struct DATA_T stTemp; printf("8. sizeof(struct DATA_T) = %d, sizeof(stTemp) = %d \n", sizeof(struct DATA_T), sizeof(stTemp)); return 0; }得到的結果是:
8. sizeof(struct DATA_T) = 36, sizeof(stTemp) = 36
問題來了,DATA_T這個結構,也是由7種不一樣的資料型態所組成。所以,理論上這個DATA_T所佔用的記憶體空間應為:
4 + 2 + 4 + 4 + 1 + 8 + 8 = 31
應該要31 Bytes才對,為什麼會變成36呢??這就是電腦幫我們做最佳化的處理。把記憶體的空間最佳化為2的倍數。
承以上程式碼,我們再多加一行:
#include <stdio.h> #define __PACK__ __attribute__((packed)) struct DATA_T { int nTemp; short int snTemp; long lnTemp; float fTemp; char cTemp; long long lnlnTemp; double dTemp; } __PACK__; int main(void) { struct DATA_T stTemp; printf("9. sizeof(struct DATA_T) = %d, sizeof(stTemp) = %d \n", sizeof(struct DATA_T), sizeof(stTemp)); return 0; }這次所得到的結果:
9. sizeof(struct DATA_T) = 31, sizeof(stTemp) = 31
就如同我們所期待地一樣了!!其中第二個程式碼的範例,在一般的PC上基本上是沒有什麼問題的;若是在記憶體寸土寸金的嵌入式系統上,可就不行了。
若想要瞭解更多__attribute__((packed))的用法,請參閱 (其實是我懶的寫....XD):
http://huenlil.pixnet.net/blog/post/26078382
沒有留言:
張貼留言