sizeof的32位和64位相容問題
周海漢 2010.12.15 http://abloz.com
問題: linux下編寫一個普通的列印語句: printf(“sizeof int is %d”, sizeof(int)); 編譯時會得到如下的warning: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘long unsigned int’ 原始碼:
////////////////////////////////////////// //author zhouhh //date 2010.12.15 //notes testsizeof.c //history //http://abloz.com copyright( 2010 ) allright reserved! ///////////////////////////////////////// #include <stdio.h> void main() { printf("sizeof int=%d",sizeof(int)); }
[email protected]:~/test$ gcc -o ts testsizeof.c testsizeof.c: In function ‘main’: testsizeof.c:13: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘long unsigned int’
問題原因 這是因為我的系統是64位的,sizeof返回的size_t型別定義為long unsigned int. [email protected]:~/test$ uname -a Linux zhh64 2.6.35-24-generic #42-Ubuntu SMP Thu Dec 2 02:41:37 UTC 2010 x86_64 GNU/Linux
而對32位系統,不會產生該warning。因為32為的size_t型別是unsigned int. 那如果程式需要在32和64位系統保持相容性,不希望產生該warning,如何處理呢?
問題解決 1.強制轉換size_t為unsigned int. 這種方式可以去掉warning,但有截斷,只能是權宜之計。 2.原來printf已經為該相容性定義了新的格式字元z。 修改原始碼:
1 ////////////////////////////////////////// 2 //author zhouhh 3 //date 2010.12.15 4 //notes testsizeof.c 5 //web http://abloz.com 6 //copyright( 2010 ) allright reserved! 7 ///////////////////////////////////////// 8 9 #include <stdio.h> 10 11 void main() 12 { 13 printf("sizeof int=%zu",sizeof(int)); 14 }
再編譯,32位和64位系統都不會有warning。 [email protected]:~/test$ gcc -o ts testsizeof.c [email protected]:~/test$ ./ts sizeof int=4
深究: printf 為長度的相容性定義了一系列的格式化字元: man 3 printf:
The length modifier
Here, "integer conversion" stands for d, i, o, u, x, or X conversion.
hh A following integer conversion corresponds to a signed char or
unsigned char argument, or a following n conversion corresponds
to a pointer to a signed char argument.
h A following integer conversion corresponds to a short int or
unsigned short int argument, or a following n conversion corre‐
sponds to a pointer to a short int argument.
l (ell) A following integer conversion corresponds to a long int
or unsigned long int argument, or a following n conversion cor‐
responds to a pointer to a long int argument, or a following c
conversion corresponds to a wint_t argument, or a following s
conversion corresponds to a pointer to wchar_t argument.
ll (ell-ell). A following integer conversion corresponds to a long
long int or unsigned long long int argument, or a following n
conversion corresponds to a pointer to a long long int argument.
L A following a, A, e, E, f, F, g, or G conversion corresponds to
a long double argument. (C99 allows %LF, but SUSv2 does not.)
q ("quad". 4.4BSD and Linux libc5 only. Don't use.) This is a
synonym for ll.
j A following integer conversion corresponds to an intmax_t or
uintmax_t argument.
z A following integer conversion corresponds to a size_t or
ssize_t argument. (Linux libc5 has Z with this meaning. Don't
use it.)
t A following integer conversion corresponds to a ptrdiff_t argu‐
ment.
可以看到z 是專門針對size_t和ssize_t列印的。遇到類似問題可以到上面找一找。
如非註明轉載, 均為原創. 本站遵循知識共享CC協議,轉載請註明來源