수색…


통사론

  • _Generic (할당 표현식, generic-assoc-list)

매개 변수

매개 변수 세부
generic-assoc-list 일반 협회 또는 일반 연합 단체 목록, 일반 단체
일반 협회 type-name : 할당 표현식 OR 기본값 : 할당 표현식

비고

  1. _Generic 1 차 표현식을 평가하는 동안 모든 유형 규정자가 제거됩니다.
  2. _Generic 기본 표현은 번역 단계 7 에서 평가됩니다. 따라서 문자열 연결과 같은 단계는 평가 전에 완료되었습니다.

변수가 특정 한정 유형인지 확인하십시오.

#include <stdio.h> 

#define is_const_int(x) _Generic((&x),  \
        const int *: "a const int",     \
        int *:       "a non-const int", \
        default:     "of other type")

int main(void)
{
    const int i = 1;
    int j = 1;
    double k = 1.0;
    printf("i is %s\n", is_const_int(i));
    printf("j is %s\n", is_const_int(j));
    printf("k is %s\n", is_const_int(k));
}

산출:

i is a const int
j is a non-const int
k is of other type

그러나 유형 generic 매크로가 다음과 같이 구현되면 :

#define is_const_int(x) _Generic((x), \
        const int: "a const int",     \
        int:       "a non-const int", \
        default:   "of other type")

출력은 다음과 같습니다.

i is a non-const int
j is a non-const int
k is of other type

이것은 _Generic 기본 표현식의 제어 표현식을 평가하기 위해 모든 유형 규정자가 제거되기 때문입니다.

유형 일반 인쇄 매크로

#include <stdio.h>

void print_int(int x) { printf("int: %d\n", x); }
void print_dbl(double x) { printf("double: %g\n", x); }
void print_default() { puts("unknown argument"); }

#define print(X) _Generic((X), \
        int: print_int, \
        double: print_dbl, \
        default: print_default)(X)

int main(void) {
    print(42);
    print(3.14);
    print("hello, world");
}

산출:

int: 42
double: 3.14
unknown argument

유형이 int 또는 double 이 아닌 경우 경고가 생성됩니다. 경고를 없애기 위해 해당 유형을 print(X) 매크로에 추가 할 수 있습니다.

여러 인수를 기반으로 일반 선택

유형 일반 표현식에 대한 여러 인수에 대한 선택이 필요하고 문제의 모든 유형이 산술 유형 인 경우 중첩 된 _Generic 표현식을 피하는 쉬운 방법은 제어 표현식에 매개 변수를 추가하는 것입니다.

int max_int(int, int);
unsigned max_unsigned(unsigned, unsigned);
double max_double(double, double);

#define MAX(X, Y) _Generic((X)+(Y),                \
                           int:      max_int,      \
                           unsigned: max_unsigned, \
                           default:  max_double)   \
                    ((X), (Y))

여기서 제어식 (X)+(Y) 는 유형에 따라 검사되며 평가되지 않습니다. 선택한 유형을 판별하기 위해 산술 피연산자의 일] 변환이 수행됩니다.

보다 복잡한 상황의 경우 연산자를 둘 이상의 인수에 기초하여 함께 중첩하여 선택을 할 수 있습니다.

이 예제는 두 개의 int 및 / 또는 string 인수의 조합을 취하고 그 합을 반환하는 네 가지 외부 구현 함수 중에서 선택합니다.

int AddIntInt(int a, int b);
int AddIntStr(int a, const char* b);
int AddStrInt(const char*  a, int b );
int AddStrStr(const char*  a, const char*  b);

#define AddStr(y)                            \
   _Generic((y),         int: AddStrInt,     \
                        char*: AddStrStr,    \
                  const char*: AddStrStr )

#define AddInt(y)                            \
   _Generic((y),          int: AddIntInt,    \
                        char*: AddIntStr,    \
                  const char*: AddIntStr )

#define Add(x, y)                            \
   _Generic((x) ,        int: AddInt(y) ,    \
                       char*: AddStr(y) ,    \
                 const char*: AddStr(y))     \
                         ((x), (y))

int main( void )
{
    int result = 0;
    result = Add( 100 , 999 );
    result = Add( 100 , "999" );
    result = Add( "100" , 999 );
    result = Add( "100" , "999" );

    const int a = -123;
    char b[] = "4321";
    result = Add( a , b );

    int c = 1;
    const char d[] = "0";
    result = Add( d , ++c );
}

인수 y 가 두 번 이상 평가되는 것처럼 보이지만 1 이 아닙니다. 두 인수는 일반 함수 호출과 마찬가지로 Add : ( x , y ) 매크로 끝에 한 번만 평가됩니다.


1 (인용 : ISO : IEC 9899 : 201X 6.5.1.1 일반 선택 3)
일반 선택의 제어 표현식은 평가되지 않습니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow