32 비트 아키텍처에서 GCC 컴파일에 다음과 같은 경고를 받았지만 64 비트 아키텍처에서는 그러한 경고가 없습니다.

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

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

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top