C 프로그래밍에서 va_list는 가변 인자 함수(variable-argument function)를 구현할 때 사용되는 매크로다.
이 매크로는 함수가 인자의 개수를 고정하지 않고, 다양한 개수의 인자를 받을 수 있도록 한다.
printf 함수처럼 여러 개의 인자를 받아서 출력할 수 있는 함수에서 사용된다.
#include <stdio.h>
int main()
{
printf("%d, %s", 100, "print va_list";
return (0);
}
100, "print va_list" 와같이 가변적으로 인자를 받을 때 사용된다.가변 인자 함수는 인자의 개수가 고정되지 않기 때문에, 이를 처리하기 위해 va_list와 함께 va_start, va_arg, va_end 같은 매크로를 사용한다.
va_list는 기본적으로 가변 인자 목록을 담는 자료형이다.
가변 인자를 순차적으로 처리하는 포인터 역할을 한다.
함수가 호출될 때, va_list는 가변 인자 목록의 시작 주소를 가리키고, 이후에 va_arg 매크로를 통해 각 인자를 하나씩 꺼내서 사용할 수 있다.
가변 인자 함수가 호출되면, 컴파일러는 인자 목록을 스택에 저장한다.
va_list는 이 스택의 첫 번째 인자를 가리키도록 초기화된가.
va_start 매크로가 이를 설정하고, va_arg를 사용해 인자들을 순차적으로 추출한 후, va_end로 리소스를 정리한다.
va_list: 가변 인자 목록을 처리할 수 있는 포인터.va_start:va_list를 가변 인자 목록의 시작을 가리키도록 초기화.va_arg: 현재 인자를 리턴하고,va_list를 증가시켜 다음 인자를 가리키게 함.va_end:va_list를 초기화하고 리소스를 정리.
va_list를 사용 하기 위해서는 헤더는 stdarg.h로 사용한다.
가변 인자 함수를 정의할 때는 다음과 같은 형식으로 작성된다.
#include <stdio.h>
#include <stdarg.h>
void testit (int i, ...)
{
va_list argptr;
va_start(argptr, i);
if (i == 0)
{
int n = va_arg(argptr, int);
printf("%d\n", n);
}
else
{
char *s = va_arg(argptr, char*);
printf("%s\n", s);
}
va_end(argptr);
}
int main()
{
testit(0, 0xFFFFFFFF); // 1st problem: 0xffffffff is not an int
testit(1, NULL); // 2nd problem: NULL is not a char*
}
i는 고정 인자이고, 뒤따르는 ...는 가변 인자를 의미한다.va_list argptr: argptr는 가변 인자들을 처리하는 데 사용될 변수이다.va_start(argptr, i): 가변 인자 목록을 초기화하며, i가 마지막 고정 인자이기 때문에 이를 기준으로 가변 인자들이 시작된다.main 함수
main에 호출하여 코드를 작성하였는데 가변인자 입력값이 문제가 있다.OUTPUT
-1
(null)
0xFFFFFFFF는 unsigned int,NULL은 void*로 타입이 다르기에segmentation fault가 일어날 수 있어 형변환이 적절히 있어야 한다.va_list와 관련된 가변 인자 함수는 유용하게 사용될 수 있지만, 타입 일치를 신경 써야 한다. 잘못된 타입으로 인자를 추출하면 예기치 않은 동작이나 오류가 발생할 수 있다. 참고자료
learn.microsoft
ibm
가변인자 뜯어보기