IT한 것/unix

passing argument ... with different width due to prototype

lovian 2011. 9. 23. 15:31
gcc를 이용하여 컴파일을 하다보면, 자주 보게되는 경고문이다.

먼저 선언해두었던 함수의 원형과는 일치하지않는 전달인자를 넘겼을 경우에 발생한다.
물론 -Wconversion 옵션을 설정하지 않으면 발생하지 않겠지만, 꼼꼼하게 하려는 생각에 사용한다.

그런데 참 이해하기 힘든 상황이 발생했었다.

lovian$ cat a.c
int func (unsigned char aa)
{
    return 1;
}
int main ()
{
    func ((unsigned char)0);
    return 0;
}

lovian$ gcc a.c -Wconversion
a.c: In function ‘main’:
a.c:7: warning: passing argument 1 of ‘func’ with different width due to prototype
lovian$ g++ a.c -Wconversion
lovian$

보다시피 함수 원형에 맞은 형식으로 변환하여 전달하였지만, 경고문이 발생한다.
그런데! c++로 컴파일을 하니 또 경고문이 없다.

문제는 내부적인 것에 있었다.

호출규약과 관련이 없지 않다.
보통 전달인자를 실제 함수에 넘겨주기 위해서 CPU의 레지스터와, stack을 이용한다.
이 두 전달방법은 각각의 크기가 몇 바이트 이상인데,
하나의 전달인자는 하나의 레지스터, stack에 들어가므로 내부적으로는
1바이트의 전달인자라고 할지라도 레지스터 크기, stack의 크기가 전달되는 것이다.

결국 1바이트를 던져도, 내부적으로는 4바이트 이상이 사용될 것이므로 (32비트의 경우?),
일반적인 C에서는 int 형식으로 변환하는 것으로 보여진다.

C++ 컴파일러에서는 자체적으로 각각의 레지스터나 stack을 쪼개서 사용하는지도 모르겠다.
하지만, 굳이 어셈블리 코드로 보기에는 필 의미가 없어보이는 귀차니즘... :-)


하여튼, char 형식으로 전달인자를 사용하는 경우에는 귀찮은 경고를 만날 수 있다.
왠만하면 피해보자 ㅋㅋㅋ