Ich habe die folgende Warnung in der GCC -Zusammenstellung in 32 -Bit -Architektur, aber keine solche Warnung in 64 -Bit -Architektur
-
19-09-2019 - |
Frage
Symbol.c: In der Funktion '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_FinishErrorReport();
1203 }
1204 #endif
1205 }
1206 else if (symbol_SignatureExists())
1207 fputs(symbol_Name(Symbol), File);
1208 else
1209 fprintf(File, "%ld", Symbol);
1210 }
Und Symbol wird definiert als:
typedef size_t SYMBOL
Als ich '%ld' durch '%zu' ersetzte, bekam ich die folgende Warnung:
symbol.c: In function 'symbol_FPrint':
symbol.c:1209: warning: ISO C90 does not support the 'z' printf length modifier
Hinweis: Von hier aus wurde es am 26. März 2010 bearbeitet, und und das Problem wurde aufgrund seiner Ähnlichkeit mit dem oben genannten Problem hinzugefügt.
Ich habe die folgende Erklärung:
printf("\n\t %4d:%4d:%4d:%4d:%4d:%s:%d", Index, S->info, S->weight,
Precedence[Index],S->props,S->name, S->length);
Die Warnung, die ich beim Kompilieren in 64 -Bit -Architektur bekomme, lautet:
format ‘%4d’ expects type ‘int’, but argument 5 has type ‘size_t’
Hier sind die Definitionen des Parameters:
NAT props;
typedef unsigned int NAT;
Wie kann ich das loswerden, damit ich in 32 und 64 -Bit -Architektur ohne Vorwarnung zusammenstellen kann?
Was kann seine Lösung sein?
Lösung
Verwenden %zu
statt %ld
als Format für size_t
Und dann erhalten Sie sowohl in 32-Bit- als auch in 64-Bit-Builds korrektes Verhalten (und keine Warnungen).
Wenn Sie aus irgendeinem Grund nicht verwenden können %zu
(ZB alter oder nicht standardmäßiges Compiler), dann können Sie so etwas tun:
#ifdef __LP64__ // if 64 bit environment
#define FMT_SIZE_T "llu"
#else
#define FMT_SIZE_T "lu"
#endif
Wenn Sie dann Printf mit etwas Typ size_t verwenden müssen, können Sie dies tun:
printf("(sizeof(void *) = %"FMT_SIZE_T" bytes \n", sizeof(void *));
Andere Tipps
ich finde %lu
das einzige C89-konforme (OR, GCC-C89-Warnings-konforme) Format für sein size_t
, unter Linux. unter glibc, size_t
scheint immer zu sein long unsigned int
, Also %lu
ist dort angemessen.
Insbesondere fand ich das GCC-4.4.3 mit -std=c89 -pedantic
oder -std=c89 -Wall
wird davor warnen %llu
und %lld
. macht Sinn, da sie erwarten long long
, ein C99 -Typ.
Tragischerweise gibt es keine Möglichkeit, a zu drucken size_t
auf plattformunabhängige C89-konforme Weise. in C89, alle printf
Formate beziehen sich auf bestimmte primitive Typen (long
, int
, usw.), aber in alle C -Dialekte, size_t
ist plattformabhängig (könnte sein long
oder int
oder etwas anderes).
Wie üblich wirft Microsoft Ihnen seinen eigenen Spezialmantelschlüssel. Die Windows-Kompilierungsumgebung ist ein schlecht modifizierter C89: Sie hat long long
, aber nein ll
printf Modifikator. In Windows-Land, %llu
wird %I64u
und %zu
wird %Iu
.
Am Ende habe ich die folgenden Codebasis meines Labors verwendet:
#ifdef _WIN32 #define PRIuZ "Iu" #else #define PRIuZ "lu" #endif
verwenden:
printf("%"PRIuZ"\n", sizeof(struct foo));
Ich habe den Namen aus den Definitionen in C99 modelliert inttypes.h
.
Nebenbei: Meine Version von Win64 Mingw-GCC (4.4.5 20100527 (Prerelease) [SVN/Rev.159909-Mingw-w64/oz]) plus -Wall
oder -pedantic
, stets warnt beim Drucken a size_t
. es beschwert sich %I64u
und %Iu
sind nicht standardmäßig, und das %lu
ist falsch. Scheint, als würde der Compiler durch Microsofts Wahnsinn korrekt gestolpert. Ich musste benutzen -pedantic -Wformat=0
Um es nicht zu jammern lassen %Iu
.