32 비트 아키텍처에서 GCC 컴파일에 다음과 같은 경고를 받았지만 64 비트 아키텍처에서는 그러한 경고가 없습니다.
-
19-09-2019 - |
문제
Symbol.c : 함수 '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'
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 }
기호는 다음과 같이 정의됩니다.
typedef size_t SYMBOL
'%ld'를 '%zu'로 교체하면 다음 경고가 있습니다.
symbol.c: In function 'symbol_FPrint':
symbol.c:1209: warning: ISO C90 does not support the 'z' printf length modifier
참고 : 여기에서 2010 년 3 월 26 일에 편집되었으며 위에서 언급 한 문제와 유사하기 때문에 다음과 같은 문제가 추가되었습니다.
다음 진술이 있습니다.
printf("\n\t %4d:%4d:%4d:%4d:%4d:%s:%d", Index, S->info, S->weight,
Precedence[Index],S->props,S->name, S->length);
64 비트 아키텍처로 컴파일하는 동안 얻는 경고는 다음과 같습니다.
format ‘%4d’ expects type ‘int’, but argument 5 has type ‘size_t’
매개 변수의 정의는 다음과 같습니다.
NAT props;
typedef unsigned int NAT;
32 및 64 비트 아키텍처에서 경고없이 컴파일 할 수 있도록이를 제거하려면 어떻게해야합니까?
솔루션이란 무엇입니까?
해결책
사용 %zu
보다는 %ld
형식으로 size_t
그런 다음 32 비트 및 64 비트 빌드에서 올바른 행동 (및 경고가 없음)을 얻을 수 있습니다.
어떤 이유로 든 사용할 수없는 경우 %zu
(예 : 구식 또는 비표준 컴파일러), 다음과 같은 일을 할 수 있습니다.
#ifdef __LP64__ // if 64 bit environment
#define FMT_SIZE_T "llu"
#else
#define FMT_SIZE_T "lu"
#endif
그런 다음 simegy _t의 somethign과 함께 printf를 사용해야 할 때 다음을 수행 할 수 있습니다.
printf("(sizeof(void *) = %"FMT_SIZE_T" bytes \n", sizeof(void *));
다른 팁
나는 찾았다 %lu
유일한 C89- 호환 (또는 GCC-C89-Warnings Compliant) 형식이 되려면 size_t
, Linux에서. glibc 아래, size_t
항상있는 것 같습니다 long unsigned int
, 그래서 %lu
거기에 적합합니다.
특히 나는 GCC-4.4.3을 발견했다 -std=c89 -pedantic
또는 -std=c89 -Wall
경고 할 것입니다 %llu
그리고 %lld
. 그들이 기대하기 때문에 의미가 있습니다 long long
, C99 유형.
비극적으로 인쇄하는 방법이 없습니다 size_t
플랫폼 독립적 인 C89 대응 방식으로. C89에서 모두 printf
형식은 특정 원시 유형을 나타냅니다 (long
, int
, 등), 그러나 모두 C 방언, size_t
플랫폼 의존적 일 수도 있습니다 long
또는 int
또는 다른 것).
평소와 같이, Microsoft는 당신에게 자신의 특별한 원숭이 렌치를 던졌습니다. Windows 컴파일 환경은 잘못 수정 된 C89입니다. long long
, 하지만 ll
printf 수정 자. Windows-Land에서 %llu
becomes %I64u
그리고 %zu
becomes %Iu
.
실험실의 코드베이스에서 다음을 사용하게되었습니다.
#ifdef _WIN32 #define PRIuZ "Iu" #else #define PRIuZ "lu" #endif
사용:
printf("%"PRIuZ"\n", sizeof(struct foo));
C99의 정의에서 이름을 모델링했습니다. inttypes.h
.
따로 : 내 버전의 Win64 Mingw-GCC (4.4.5 20100527 (Prerelease) [SVN/Rev.159909-MINGW-W64/OZ]), Plus -Wall
또는 -pedantic
, 언제나 인쇄 할 때 경고합니다 size_t
. 그것은 그것을 불평합니다 %I64u
그리고 %Iu
비표준입니다 %lu
부정확하다. Microsoft의 광기에 의해 컴파일러가 올바르게 넘어지고있는 것 같습니다. 나는 사용해야했다 -pedantic -Wformat=0
그것을 걱정하지 않도록하기 위해 %Iu
.