[C] va_list(가변인자)란?

Austin·2024년 11월 22일

C언어

목록 보기
1/5

va_list란?

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_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의 사용 방법 🛠️

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가 마지막 고정 인자이기 때문에 이를 기준으로 가변 인자들이 시작된다.
  • if (i == 0) 조건에 따라, 가변 인자가 어떤 타입인지를 다르게 처리한다.
    i == 0인 경우 va_arg(argptr, int)를 사용하여 첫 번째 가변 인자를 int로 읽는다.
    그렇지 않은 경우 va_arg(argptr, char)를 사용하여 char 타입으로 가변 인자를 읽는다.
  • va_end(argptr): 가변 인자 목록을 모두 처리한 후에는 va_end로 정리 작업을 한다.

main 함수

  • 가변인자 함수를 main에 호출하여 코드를 작성하였는데 가변인자 입력값이 문제가 있다.
OUTPUT
-1
(null)
  • 이렇게 나올 수도 있지만 0xFFFFFFFFunsigned int,NULLvoid*로 타입이 다르기에segmentation fault가 일어날 수 있어 형변환이 적절히 있어야 한다.
  • va_list와 관련된 가변 인자 함수는 유용하게 사용될 수 있지만, 타입 일치를 신경 써야 한다. 잘못된 타입으로 인자를 추출하면 예기치 않은 동작이나 오류가 발생할 수 있다.

참고자료
learn.microsoft
ibm
가변인자 뜯어보기

0개의 댓글