가변인자 함수 관련
intro
char a = 3;
printf("%d", a);
어째서 위와 같은 코드는 동작하는 것일까?
상식적으로 생각해 보면 FSF로 %d를 사용하였으니까 sizeof(int)
만큼(통상 4byte 만큼) 읽어올 것이고, 그래서 char
형인 a가 주어졌으니까 오류가 날 것처럼 보인다.
그러나 저 코드는 100% 정상 작동하는 아주아주 적법한 코드이다.
왜 그런 것일까? 이는 가변인자 함수가 굴러가는 방식과 밀접한 관련이 있다.
가변인자? 가변인자!
printf
같은, 이미 표준 라이브러리에 구현된 가변인자 함수를 써 본 경험이야 다들 몇 번 있을 것이다.
그러나 직접 가변인자를 받는 함수를 만들어 본 적은 거의 없을 것이라고 생각한다. 사실 가변인자 함수를 새로 만드는걸 권장하지도 않는다.
왜냐하면, 생각보다 쓸 일이 별로 없고, 비효율적이고, 버그가 생기기도 쉽기 때문이다.
아마 가변인자 함수가 어떤 식으로 처리되는지 보면 바로 감이 올 것이다.
왜 쓰레기인가
/* 적당한 가변인자 함수*/
int var_arg_test(const char *format, ...)
{
va_list va; // 가변인자들이 싹 다 들어있는 리스트
va_start(va, format);
double a = va_arg(va, double); // 타입에 맞춰서 읽어옴.
/*...적당히 섹시한 코드...*/
va_end(va);
}
/*이후 생략*/
뭐가 뭔지는 대충 알거라고 생각하고, 왜 쓰레기인지만 간단하게 설명하도록 하겠다.
- 쓰레기인 이유 1
주목해야 할 것이 저어기 저 va_arg(va, double)
부분이다. 읽는 쪽에서 타입을 지정해야 한다는, 다소 충격적인 사실을 알 수 있다.
무슨 void*
도 아니고... va_list
에 들어있는 가변인자들은 타입관련 정보가 날아가버린 상태다. 심지어 va_list
에 가변인자가 몇 개나 들어있는지도 모른다.
그냥 va_arg
를 사용해서 타입 맞춰서 읽어오는게 끝이다. 받는 쪽에서 알아서 타입을 맞춰서 읽어와야된다는게 얼마나 개떡같은 구현인지는 말 안해도 알거라고 생각한다.
그리고 왜 format specifier를 쓰는지, 왜 칼같이 format specifier를 맞춰야 하는지에 대해서도 알게 되었을 것이다.
거기 말고는 인자들 정보를 읽어올 데가 없으니까...
- 쓰레기인 이유 2
그 다음으로 쓰레기 같은 부분은, default argument promotion
이랑 깊은 연관이 있다.
대에충 가변인자함수의 가변인자로 밀려들어간 인자들에게 일어나는 기묘한 현상이다.
char c = 3;
short d = 12;
printf("%d %d", c, d);
머 이런 코드가 있다고 할 때, 주는 쪽에서는 분명이 short
하나랑 char
하나를 넘겼다고 생각하는데...
실제로는 int
형 2개로 진급(promotion
)되서 전달된다.(일반적으로 그렇다는거고 뭐... 굳이 자세하게 적자면 산술 연산에서 일어나는 정수진급이랑 동일한 규칙을 따른다.)
추가로 float
를 넘기는 경우에도 double
로 승급되서 전달된다.
아까 비효율이 어쩌고 했던거도 이런 기묘한 특성 때문이다.
unsigned char c = 'a';
printf("%hhu\n", c);
ㄴ 위 코드 처럼 쓰면 c
는 int
로 승급해서 전달된 다음에 다시 unsigned char
로 형변환을 거쳐서 화면에 출력되게 된다. ㅈㄴ 비직관적이고 비효율적이다.
그건 그렇고 이제 왜 %d
로 char
형 변수를 출력할 수 있는지 알게 되었을 것이다.
사족
왜 이딴 일이 생기는지, 그리고 왜 가변인자 함수에서만 그러는지는 음... 옛날 옛적 C언어의 잔재라고 하겠다.
사실 가변인자 함수 말고 다른 함수에서도 일어날 수 있는 일이기는 한데... 대가리가 정위치에 놓여있는 인간이면 자기 손으로 그런 코드를 만들 일은 절대 없을거니가 뭐...
그런 시시콜콜한 것까지 자세히 설명하는건 너무 귀찮으니까, 정 궁금하면 찾아보든가 계속 궁금한 채로 살든가 하십셔.
차피 똑똑한 놈들은 이 글 안봐도 뭐 다 알고 있었을거고...
걍 개인적으로 정리하는 차원에서 써봤음.
Author And Source
이 문제에 관하여(가변인자 함수 관련), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@trashcan71074/가변인자-함수-관련저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)