Ich habe die folgende Warnung in der GCC -Zusammenstellung in 32 -Bit -Architektur, aber keine solche Warnung in 64 -Bit -Architektur

StackOverflow https://stackoverflow.com/questions/2426113

  •  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?

War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top