2009-11-23 7 views
8

나는 다음과 같은 C 코드를 한 :gcc가 "round '함수의 암시 적 선언을보고하는 이유는 무엇입니까?

#include <math.h> 

int main(int argc, char ** argv) 
{ 
    double mydouble = 100.0; 
    double whatever = round(mydouble); 

    return (int) whatever; 
} 

나는이를 컴파일 할 때, 나는 경고를 얻을 : 나는 C와 녹슬

round_test.c: In function ‘main’: 
round_test.c:6: warning: implicit declaration of function ‘round’ 
round_test.c:6: warning: incompatible implicit declaration of built-in function ‘round’ 

을,하지만 난 #INCLUDE이 선언을 가져 생각 round()에서 범위로. round() 함수가 math.h 헤더에 있음을 확인하는 ANSI 표준 (C99 만 가지고 있음)을 확인했습니다. 내가 여기서 무엇을 놓치고 있니?

편집 : 컴파일러는 Ubuntu의 GCC 4.3.2입니다 (intrepid, IIRC). gcc -E를 실행하면 다음과 같이 나타납니다.

$ gcc -E round_test.c | grep round 
# 1 "round_test.c" 
# 1 "round_test.c" 
# 2 "round_test.c" 2 
    double whatever = round(mydouble); 

따라서 헤더에 정의가 분명히 없습니다.

답변

17

gcc를 사용하고 있습니다.

기본적으로 gcc는 C89와 비슷한 표준을 사용합니다. 당신이 (이 준수 부분)

gcc -std=c99 -pedantic ... 

견적 기본적으로 GCC Manual

에서 C99 표준을 사용하는 "강제"할 수 있습니다, GCC는에 C 언어에 일부 확장을 제공 드문 경우 C 표준과 충돌합니다. C 언어 제품군의 확장을 참조하십시오. 위에 나열된 -std 옵션을 사용하면 이러한 확장이 사용되지 않으므로 과 C 표준 버전이 충돌합니다. -std = gnu89 (GNU 확장이있는 C89의 경우) 또는 -std = gnu99 (GNU 확장이있는 C99 의 경우)로 명시 적으로 -std = gnu89 인 확장 된 버전의 C 언어를 선택할 수도 있습니다. C 언어 사투리 옵션이없는 경우 기본값은 이며 -std = gnu89입니다. C99 지원이 완료되면 을 향후 릴리스에서 으로 -std = gnu99로 변경합니다. 표준의 일부인 C99 기능은 C89 모드의 확장으로 허용됩니다.

+1

감사합니다. -std = c99가 문제를 해결 한 것 같습니다. 나는 round()가 C99 추가 였음을 깨닫지 못했다. (그리고 물론 내 모든 참조는 C99이고 이것을 언급하는 것을 게을리한다.) –

+0

(놀란 표정) round()는 정말로 C99 추가인가? –

+0

맞아요, C89는'round()'함수를 설명하지 않았습니다 (물론 컴파일러는 그것을 확장으로 제공 할 수 있습니다). – pmg

3

gcc 설치, 시스템 헤더 또는 컴파일 옵션에 문제가있어 야합니다.

-E를 사용하여 컴파일 해보십시오. 그러면 어떤 헤더가 포함되어 있고 무엇이 들어 있는지 등 프리 프로세서가 출력 한 내용이 표시됩니다.

extern double round (double __x) __attribute__ ((__nothrow__)) __attribute__ ((__const__)); 
+0

나는 우분투 9.10 (Karmic)에 있습니다. 여기서'#include '은 선언을 포함하고있는 /usr/include/bits/mathcalls.h를 적재하는 /usr/include/math.h를 적재합니다. –

0

입력 코드는 GCC 4.0.1와 맥 OS X 10.5.8에 깨끗하게 컴파일 : 내 우분투 리눅스 시스템에 그것은이 포함 출력의 약 1000 라인을합니다. '-Wall -Wextra'옵션을 사용하면 argc와 argv라는 미사용 매개 변수에 대해 불만을 토로합니다.

컴퓨터에서 <math.h>을 보았습니까?

'-stc = c99'와 같은 옵션을 사용해 보셨습니까?

3

당신은 당신이 C99을 원하는 GCC 말할 필요, 당신은 libm의 링크를하려는 : 당신이 수학 라이브러리와 링크해야

gcc -std=c99 -lm round_test.c 
-2

. 따라서 컴파일 할 때 -lm 플래그를 추가해야합니다.

+1

입력 해 주셔서 감사합니다. 그러나 이것은 링크 문제가 아닌 컴파일 문제입니다. 나는 내 컴파일러 명령 (내 잘못)을 버린 것을 깨달았지만, gcc -c로 컴파일하고 있었다. –

0

C99가 답변이지만 전체 내용은 좀 더 복잡합니다. 내가 이와 같이 놀았던 이유는 round()에 대한 자체 최적화 된 정의가있는 Windows 용 라이브러리를 컴파일하려고 시도했기 때문입니다. 정의가 내장과 충돌한다는 링커 오류가있어서 정의 (및 선언)를 제거했습니다. 일단 내가했으면 "암시적인 선언 오류"를 받기 시작했다.

기본 컴파일 모드 (-std = c99 플래그 없음)가 C89 또는 C99를 준수하지 않는 것으로 보입니다. C89를 준수하는 경우 충돌없이 round()의 사용자 지정 정의를 제공 할 수 있어야합니다. 그것이 C99을 따르고 있다면 선언은 math.h에 있어야합니다.

+1

기본 모드는'-std = gnu89'입니다. :) – pmg

관련 문제