1. 程式人生 > >sizeof的32位和64位相容問題

sizeof的32位和64位相容問題

2010-12-15

周海漢 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協議,轉載請註明來源