I have having following warning in gcc compilation in 32 bit architecture but not having any such warning in 64 bit architecture
symbol.c: In function 'symbol_FPrint':
symbol.c:1209: warning: format '%ld' expects type 'long int', but argument 3 has type 'SYMBOL'
symbol.c: In function 'symbol_FPrintOtter':
symbol.c:1236: warning: format '%ld' expects type 'long int', but argument 3 has type 'SYMBOL'
symbol.c:1239: warning: format '%ld' expects type 'long int', but argument 3 has type 'SYMBOL'
symbol.c:1243: warning: format '%ld' expects type 'long int', but argument 3 has type 'SYMBOL'
symbol.c:1266: warning: format '%ld' expects type 'long int', but argument 3 has type 'SYMBOL'
In symbol.c
1198 #ifdef CHECK
1199 else {
1200 misc_StartErrorReport();
1201 misc_ErrorReport("\n In symbol_FPrint: Cannot print symbol.\n");
1202 misc_F开发者_如何学CinishErrorReport();
1203 }
1204 #endif
1205 }
1206 else if (symbol_SignatureExists())
1207 fputs(symbol_Name(Symbol), File);
1208 else
1209 fprintf(File, "%ld", Symbol);
1210 }
And SYMBOL is defined as:
typedef size_t SYMBOL
When i replaced '%ld' with '%zu' , i got the following warning:
symbol.c: In function 'symbol_FPrint':
symbol.c:1209: warning: ISO C90 does not support the 'z' printf length modifier
Note: From here it has been edited on 26th of march 2010 and and following problem has beeen added because of its similarity to the above mentioned problem.
I have following statement:
printf("\n\t %4d:%4d:%4d:%4d:%4d:%s:%d", Index, S->info, S->weight,
Precedence[Index],S->props,S->name, S->length);
The warning I get while compiling in 64 bit architecture is :
format ‘%4d’ expects type ‘int’, but argument 5 has type ‘size_t’
here are the definitions of parameter:
NAT props;
typedef unsigned int NAT;
How can i get rid of this so that i can compile without warning in 32 and 64 bit architecture?
What can be its solution?
Use %zu
rather than %ld
as the format for size_t
and then you'll get correct behaviour (and no warnings) in both 32-bit and 64-bit builds.
If for some reason you can't use %zu
(e.g. old or non-standard compiler), then you can do something like this:
#ifdef __LP64__ // if 64 bit environment
#define FMT_SIZE_T "llu"
#else
#define FMT_SIZE_T "lu"
#endif
Then when you need to use printf with somethign of type size_t you can do this:
printf("(sizeof(void *) = %"FMT_SIZE_T" bytes \n", sizeof(void *));
i find %lu
to be the only C89-compliant (or, gcc-c89-warnings-compliant) format for size_t
, on linux. under glibc, size_t
seems to always be long unsigned int
, so %lu
is appropriate there.
in particular i found that gcc-4.4.3 with -std=c89 -pedantic
or -std=c89 -Wall
will warn about %llu
and %lld
. makes sense, since they expect long long
, a C99 type.
tragically there isn't a way to print a size_t
in a platform-independent C89-compliant way. in C89, all printf
formats refer to specific primitive types (long
, int
, etc), but in all C dialects, size_t
is platform-dependent (might be long
or int
or something else).
as usual, microsoft throws you its own special monkey wrench. the windows compilation environment is a badly-modified C89: it has long long
, but no ll
printf modifier. in windows-land, %llu
becomes %I64u
and %zu
becomes %Iu
.
i ended up using the following in my lab's codebase:
#ifdef _WIN32 #define PRIuZ "Iu" #else #define PRIuZ "lu" #endif
use:
printf("%"PRIuZ"\n", sizeof(struct foo));
i modeled the name from the definitions in C99's inttypes.h
.
aside: my version of win64 mingw-gcc (4.4.5 20100527 (prerelease) [svn/rev.159909 - mingw-w64/oz]), plus -Wall
or -pedantic
, always warns when printing a size_t
. it complains that %I64u
and %Iu
are nonstandard, and that %lu
is incorrect. seems like the compiler is correctly getting tripped up by microsoft's insanity. i had to use -pedantic -Wformat=0
to get it to not whine about %Iu
.
精彩评论