Computer >> 컴퓨터 >  >> 프로그래밍 >> C 프로그래밍

C 언어의 _Generic 키워드 완벽 정리: 타입별 매크로 처리 방법

C 프로그래밍 언어에서 _Generic 키워드는 서로 다른 데이터 타입에 대해 각각 다르게 동작하는 매크로(MACRO)를 정의할 때 사용됩니다. 이 키워드는 C11 표준에서 새롭게 도입되었으며, 프로그래머가 매크로를 더욱 효율적으로 활용할 수 있도록 도와줍니다.

_Generic의 핵심 동작 원리는 전달된 변수의 데이터 타입을 기준으로 매크로가 어떤 표현식으로 변환될지 결정한다는 점입니다. 마치 C++의 함수 오버로딩과 유사한 기능을 C 언어에서 구현할 수 있게 해주는 셈입니다.

_Generic 기본 문법

매크로를 여러 타입에 대응하도록 선언하는 일반적인 형태는 다음과 같습니다.

#define dec(x) _Generic((x), long double : decl, \
 default : inc, \
 float : incf)(x)

위 문법처럼 _Generic(제어식, 타입1: 표현식1, 타입2: 표현식2, ..., default: 기본표현식) 형태로 작성하면, 제어식의 타입에 따라 컴파일 시점에 해당 표현식이 선택됩니다.

예제 코드

아래 예제는 전달된 값의 데이터 타입에 따라 서로 다른 숫자를 반환하는 매크로를 정의한 코드입니다.

#include <stdio.h>
#define typecheck(T) _Generic( (T), char: 1, int: 2, long: 3, float: 4, default: 0)
int main(void) {
    printf("long 값을 매크로에 전달, 결과는 %d \n", typecheck(2353463456356465));
    printf("float 값을 매크로에 전달, 결과는 %d \n", typecheck(4.32f));
    printf("int 값을 매크로에 전달, 결과는 %d \n", typecheck(324));
    printf("문자열을 매크로에 전달, 결과는 %d \n", typecheck("Hello"));
    return 0;
}

실행 결과

long 값을 매크로에 전달, 결과는 3
float 값을 매크로에 전달, 결과는 4
int 값을 매크로에 전달, 결과는 2
문자열을 매크로에 전달, 결과는 0

동작 방식 분석

위 코드에서 typecheck 매크로는 인자로 받은 값의 타입을 판별하여 다음과 같이 동작합니다.

  • char 타입 → 1 반환
  • int 타입 → 2 반환
  • long 타입 → 3 반환
  • float 타입 → 4 반환
  • 그 외 모든 타입(default) → 0 반환

예를 들어 2353463456356465는 int 범위를 초과하므로 long 타입으로 해석되어 3이 출력되고, 4.32f는 float 리터럴이므로 4가 출력됩니다. 반면 문자열 "Hello"는 목록에 없는 타입(char 포인터)이므로 default인 0이 반환됩니다.

_Generic 사용 시 주의사항

  • _Generic은 컴파일 타임에 평가되므로 런타임 오버헤드가 없습니다.
  • 타입 목록에는 중복된 타입을 지정할 수 없습니다.
  • 모든 경우를 커버하기 위해 default 항목을 두는 것이 안전합니다.
  • 배열이나 문자열 리터럴은 자동으로 포인터 타입으로 변환(decay)되므로 주의해야 합니다.

이처럼 _Generic 키워드를 활용하면 하나의 매크로 이름으로 여러 데이터 타입을 지원하는 타입 제네릭(type-generic) 프로그래밍을 C 언어에서도 손쉽게 구현할 수 있습니다. 수학 라이브러리의 tgmath.h가 대표적인 활용 사례입니다.