2010-03-11 18 views
2

symbol.c: En fonction 'symbol_FPrint':j'avoir avertissement suivant dans la compilation gcc en architecture 32 bits, mais ne pas avoir un tel avertissement dans l'architecture 64 bits

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' 

Dans symbol.c

1198 #ifdef CHECK 
1199  else { 
1200  misc_StartErrorReport(); 
1201  misc_ErrorReport("\n In symbol_FPrint: Cannot print symbol.\n"); 
1202  misc_FinishErrorReport(); 
1203  } 
1204 #endif 
1205 } 
1206 else if (symbol_SignatureExists()) 
1207  fputs(symbol_Name(Symbol), File); 
1208 else 
1209  fprintf(File, "%ld", Symbol); 
1210 } 

et le symbole est défini comme:

typedef size_t SYMBOL 

Lorsque j'ai remplacé '% ld' avec '% zu', j'ai eu l'avertissement suivant:

symbol.c: In function 'symbol_FPrint': 
symbol.c:1209: warning: ISO C90 does not support the 'z' printf length modifier 

Note: De là, il a été modifié le 26 mars 2010 et problème suivant et a ajouté beeen en raison de sa similitude avec le problème mentionné ci-dessus.

J'ai déclaration suivante:

printf("\n\t %4d:%4d:%4d:%4d:%4d:%s:%d", Index, S->info, S->weight, 
     Precedence[Index],S->props,S->name, S->length); 

L'avertissement que je reçois lors de la compilation en architecture 64 bits est:

format ‘%4d’ expects type ‘int’, but argument 5 has type ‘size_t’ 

voici les définitions des paramètres:

NAT props; 
    typedef unsigned int  NAT; 

Comment puis-je me débarrasser de cela afin que je puisse compiler sans avertissement dans l'architecture 32 et 64 bits?

Quelle peut être sa solution?

Répondre

4

Utilisez %zu plutôt que %ld comme format pour size_t et vous obtiendrez un comportement correct (et aucun avertissement) à la fois 32 bits et les versions 64 bits.

Si pour une raison quelconque, vous ne pouvez pas utiliser %zu (par exemple, ancien ou compilateur non standard), alors vous pouvez faire quelque chose comme ceci:

#ifdef __LP64__ // if 64 bit environment 
#define FMT_SIZE_T "llu" 
#else 
#define FMT_SIZE_T "lu" 
#endif 

Ensuite, lorsque vous devez utiliser printf avec somethign de type size_t vous pouvez le faire:

printf("(sizeof(void *) = %"FMT_SIZE_T" bytes \n", sizeof(void *)); 
+0

qui a vraiment fonctionné pour les deux, j'ai encore un nouvel avertissement sur la même ligne 0e ISO C90 ne supporte pas le modificateur de longueur gnu_printf 'z'. Quelles peuvent être les alternatives dans ce cas? – thetna

+1

Utilisez soit -std = c99 lorsque vous compilez, soit # define un spécificateur de format, par ex. 'FMT_SIZE_T' qui est # défini comme'% llu' sur les versions 64 bits et '% lu' sur les versions 32 bits. –

+0

merci beaucoup Paul.Il a vraiment travaillé. – thetna

2

je trouve %lu être le seul format C89 conforme (ou, c89-conformes-warnings-gcc) pour size_t, sur linux. sous la glibc, size_t semble toujours être long unsigned int, donc %lu est approprié là.

en particulier j'ai trouvé que gcc-4.4.3 avec -std=c89 -pedantic ou -std=c89 -Wall avertira environ %llu et %lld. est logique, car ils attendent long long, un type C99. Malheureusement, il n'est pas possible d'imprimer un size_t d'une manière conforme à la norme C89, indépendante de la plate-forme. à C89, tous les formatsprintf se réfèrent à des types primitifs spécifiques (long, int, etc.), mais dans tous les dialectes C, size_t dépend de la plateforme (peut-être long ou int ou autre chose).

comme d'habitude, microsoft vous lance sa propre clé de singe spéciale. l'environnement de compilation de Windows est un C89 mal modifié: il a long long, mais pas de modificateur printf ll. dans windows-land, %llu devient %I64u et %zu devient %Iu.

i a fini par utiliser les éléments suivants dans le code de base de mon laboratoire:

 
#ifdef _WIN32 
#define PRIuZ "Iu" 
#else 
#define PRIuZ "lu" 
#endif 

utilisation:

 
printf("%"PRIuZ"\n", sizeof(struct foo)); 

je modélise le nom des définitions C99 de inttypes.h.

côté: ma version de MinGW-gcc win64 (4.4.5 20.100.527 (préversion) [svn/rev.159909 - MinGW-w64/oz]), plus -Wall ou -pedantic, toujours met en garde contre l'impression d'un size_t. il se plaint que %I64u et %Iu ne sont pas standard, et que %lu est incorrect. On dirait que le compilateur est correctement dérangé par la folie de Microsoft. J'ai dû utiliser -pedantic -Wformat=0 pour l'obtenir à ne pas pleurnicher environ %Iu.