|
#include <stdio.h>
#include <string.h>
int main()
{
...
pStr = strtok(sData, "=");
...
} compiled without any warning or error.
#include <stdio.h>
//#include <string.h>
int main()
{
...
pStr = strtok(sData, "=");
...
} warning: assignment makes pointer from integer without a cast
#include <stdio.h>
//#include <string.h>
int main()
{
...
pStr = (char*)strtok(sData, "=");
...
} compiled without any warning or error.
Q. pStr 변수도 "char *" 형 이고 strtok에서 되돌려주는 인자도 "char *" 형이기때문에 (즉, 같은 변수 타입에서의 대입이기때문에) 아무 문제가 없을것 같은데.. 왜 이런 경고가 뜰까요?
A. 어떠한 명칭의 선언이 보이지 않은 상태에서 함수호출 수식형태에 그 명칭이 나온다면 (명칭뒤에 괄호에 쌓인 인자 리스트), 그 수식이 있는 가장 안쪽 scope 에 다음과 같은 선언이 존재하는 것처럼 호출이 이루어집니다.
extern int 명칭();
따라서, strtok 의 선언이 존재하지 않으면, strtok 의 호출이 있을 때 아래와 같은 선언이 있는 것처럼 다루어지는 것입니다.
extern int strtok();
물론, strtok() 의 원래 정의와 이 선언 (이러한 선언을 implicit declaration 이라고 합니다) 은 호환되지 않으므로, 프로그램 실행의 행동은 기술적으로 undefined 가 됩니다. 어찌되었든, 저 선언에 의하면 strtok() 의 반환형은 int 형인데, 그 값을 캐스트 없이 포인터형인 char * 에 대입하려 하므로, 아래와 같은 경고가 (사실상 표준에 의해 요구되는 진단 - diagnostic - 입니다) 발생하는 것입니다.
경우에 따라, implicit declaration 이 유용히 쓰일 수 있을지 모르나,그러한 선언에 의존하는 행동은 그 호출이 잘 정의되는 경우라 해도 바람직하지 않습니다. 표준은 라이브러리 함수를 사용하는 여러가지 방법을 제공하고 있지만, 원칙적으로 관련된 헤더를 명시적으로 #include 해서 사용하도록 하시기 바랍니다.
Q. 프로그램에서 string.h 헤더파일을 추가해주지도 않았는데, 즉, 내 프로그램은 strtok 함수가 어디 있는지도 모르는데 어떻게 컴파일러가 strtok를 찾아서 호출해 주나요?
A. string.h 을 뒤져봐도 strtok 함수가 어디에 있는지는 적혀있지 않습니다. C 컴파일러가 기본적으로 찾는 라이브러리에 들어있을 뿐이죠.
하지만 #include <string.h> 를 해주면 strtok에대한 prototype은 정의가 되겠죠. 따라서 첫번째의 경우 warning이 발생하지 않습니다.
 ( 0)  ( 0)
|