2014-12-08 2 views
19

Windows 7 32 비트 시스템에 MinGW를 성공적으로 설치했으며 명령 줄 또는 MinGW 콘솔을 사용하여 간단한 프로그램을 컴파일하려고했습니다. 에서는 hello.c : 7 : 2 : 경고 : 유형의 형식 '% d를'예상 인수MinGW가 경고를 표시하지 않습니다.

#include <stdio.h> 
#include <stdlib.h> 
int main(void) 
{ 
    printf("%d\n" , 3.14) ; 
return 0 ; 
} 

명령 gcc -Wall hello.c는 정확한 경고를 제공합니다

코드는 printf와 문에서 의도적 인 오류가 'int'...

그러나 명령 gcc -std=c99 -Wall hello.c은 경고를 표시하지 않습니다.

모두 실행 파일 a.exe (실행 결과가 동일)을 만듭니다.

는 는

(흥미롭게 명령 gcc -std=gnu99 -Wall hello.c 경고를 제공합니다.)

이 버그, 또는 설치가 잘못 어떻게 든 갈 않은 경우 나도 몰라,하지만 모두가 컴파일러 일 이후 않을 것 성공적으로 더 큰 컴파일 프로젝트 (물론 -std = c99를 사용할 때 생략되는 동일한 경고).

일부 정보가 누락되었습니다.

(PS : 누군가가 새로운는 MinGW이있는 경우 설치,이 테스트를하시기 바랍니다.)

GCC 버전 4.8.1 (GCC)

업데이트 1 :

stdio.h를 포함하기 전에 _GNU_SOURCE 정의 gcc -Wall hello.c으로 경고를 제거합니다.

업데이트 2 (이하 관련이있을 수) : 0.000000

-std=gnu99 출력 :

printf("%lf\n" , 3.14) ; 

-std=c99 플래그 출력 컴파일 3.140000

을 그리고 컴파일 :

,451,515,
printf("%f\n" , 3.14) ; 

-std=gnu99-std=c99 출력 : 3.140000

업데이트 3 :

기능 영향을받을 것입니다 : printf와, fprintf와, 현재 snprintf, sprintf를. std=c99 옵션을 사용할 때

+0

어떤 버전입니까? 'gcc --version' – ooga

+2

나는 같은 결과를 얻는다 (또한 4.8.1). 이 버그는 나에게 버그처럼 보이기 때문에 개발자에게 알려야합니다. – ooga

+0

-Wformat을 명시 적으로 사용하면 어떨까요? –

답변

15

경고의 부족의 문제는 그것의 모양 때문에 -std=c99-std=gnu99를 사용하는 경우에 비해 사용되는 기능의 printf() 가족을위한 stdio.h 조금 다른는 MinGW 4.8.1을 사전.

참고 : TDM에서 MinGW 4.8.1을보고 있습니다. 다른 배포판이 이러한 세부 사항에서 다를 수 있습니다.

는 MinGW는 GCC가 96 비트를 사용하면서 때문에 C 런타임 및 MSVC가 long double 대해 64 비트 표현을 사용한다는 사실을 msvcrt.dll에 역사적인 의존 부동 소수점 값을 포맷 일부 호환성 문제가 있었다

(또는 128 bit on x64) 표현. 자세한 내용은 gcc: printf and long double leads to wrong output. [C - Type conversion messes up]을 참조하십시오. MinGW의 최신 버전은 libmingwex.a에 패밀리 (이름에 __mingw_ 접두사가 붙음)를 구현하여 해당 문제를 해결했습니다.

헤더 파일 _mingw.hstdio.hlibmingwex.a 구현 또는 msvcrt.dll 구현을 사용할지 여부를 구성합니다.

ANSI 준수가 요청되면 MinGW는 libmingwex.a 구현을 사용합니다 (이 구성을 얻는 다른 방법이 많이 있습니다 - 자세한 내용은 헤더를 참조하십시오). 사용자가 printf()libmingwex.a에 구현에 대한 전화를 걸어 __mingw_vfprintf()에 대한 호출 주위에 얇은 래퍼 인 printf()의 정적 인라인 구현을 정의하는 stdio.h에 의해 수행됩니다. 분명히 -Wformat은 컴파일러가 라이브러리의 일부로 생각하지 않는 printf() 제품군 함수 버전에 적용되지 않습니다. 합리적인 가정 - 컴파일러는 해당 함수에 대해 실제로 알지 못합니다. 이 문제는 적절한 함수 특성 (예 : __attribute__ ((format (printf, 1, 2))))을 정적 인라인 래퍼 함수에 적용하여 수정할 수 있습니다.

printf("%lf\n", 3.14) 인쇄 0.000000std=c99를 사용하여, __mingw_vfprintf()libmingwex.a 구현에서 버그가 보이는 당신이 발견 다른 문제. __mingw_vfprintf()은 실수로 "%lf"을 해석하여 인수가 long double임을 의미하는 것 같습니다. 나는 그다지 놀랄만 한 것이 아니다 - 나는 항상 %lfdouble 또는 long double을 의미 하는지를 조사해야한다.

+0

아주 좋아요. C 표준에서 인용하겠다. 익숙하다는 것을 알기 때문에. [ "f, 부동 소수점 숫자를 나타내는 FA double 인수 ..."] (http://www.iso-9899.info/n1570.html#7.21.6.1p8) – Sebivor

+0

'float 'to'printf()'를 호출합니다. 왜냐하면 그 타입의 인자가'double'으로 승격되기 때문입니다. 나는''% lf ''와''% f''가 동등한 형식 문자열을 사용하여''scanf()'에서 그것들을 사용할 수 있다고 가정합니다. 그러나 최근의 논평이 무엇인지 잘 모르겠습니다. '__mingwvfprintf()'는'long double '인수를 사용하여 실수로 "% lf"를 처리하는 것으로 보일 수 있습니다. ' "% lf"'및''% f "'명세. ''% lf ''는'long double' 타입과 함께 사용되어야한다고 말하지는 않습니다. –

+0

'% lf'의'l'은 명시 적으로 무시됩니다 -'% f'만으로는'double'과'float' (후자는 아래로 변환 됨)의 사용을 다룹니다. 'l'이 long ints에 대해'% ld'에 필요하다고 생각하는 사람들에게 안락함을 제공하기 위해 존재합니다. –

관련 문제