2016-10-20 6 views
4

일부 코드가 C와 C에서 컴파일하려면 ++ 나는이 몇 곳에서 사용C11의 _Generic을 사용하여 GNU C의 typeof (x)를 구현할 수 있습니까?

#ifdef __cplusplus 
    #define typeof(x) decltype(x) // works ok in most cases, except C++ reference types 
#endif 

char* a = (typeof(a)) malloc(4); 

C, 이것은 캐스트는 전적으로 불필요한입니다 char* a = (char *) malloc(4)에 컴파일하지만 void * C++로 암시 적으로 char *으로 승격되지 형변환이 존재하지 않으면 에러가 발생합니다.

GCC 나 Clang에서 -std=gnu11으로 컴파일 할 때도 마찬가지지만 ISO C11로 컴파일 할 때 어떻게해야합니까?

typeof.h: In function ‘main’: 
typeof.h:2:24: error: expected expression before ‘,’ token 
    short:  (short), \ 
         ^
typeof.h:8:13: note: in expansion of macro ‘gettype’ 
    char a = (gettype(a)) 1; 
      ^~~~~~~ 
typeof.h:8:25: error: expected ‘,’ or ‘;’ before numeric constant 
    char a = (gettype(a)) 1; 

gcc -E

라인이 확장 것을 말한다 상관없이 gettype(x)에 정의 된 유형 a의 선언에 주어진다

#define gettype(x) _Generic((x), \ 
    short:  (short), \ 
    char:  (char ), \ 
    char*:  (char *), \ 
    default:  (void *) ) 

int main (void) { 
    short a = (gettype(a)) 1; 

    return a; 
} 

그러나 : 나는 어떤 종류의 캐스팅 typeof(x)을 구현하기 위해 C11의 _Generic를 사용할 수 있다고 생각 그냥 괜찮습니다 :

short a = (_Generic((a), short: (short), char: (char), char*: (char *), default: (void *))) 1;       ^

일부 구문이 누락되었거나 C에서 단순히 _Generic을 사용하여 캐스트 코드를 생성 할 수 없습니까?

+2

'_Generic'은 매크로 밖에서 거의 사용할 수 없지만 전 처리기의 일부가 될 수 없습니다. 따라서 텍스트 대체를 제공 할 수 없습니다. – Olaf

+0

C 및 C++ 호환성이없는 것보다 완전한 C 호환성 및 C++ 호환성을 제공하는 것이 좋습니다. – user694733

+0

@ user694733 비평 해 주셔서 고맙습니다.하지만이 코드는 GCC 또는 Clang을 사용하여 C로만 컴파일 될 것입니다. C++ compat은 C90을 간신히 지원하는 MSVC 용입니다. – cat

답변

2

문제에서 당신이 원하는 것을 할 수있는 다른 방법이 생각하지 않습니다 당신이 일반 선택 내부의 부분적인 표현을 가질 수 있다는 것입니다. 가능한 한 해결할 수있는 내부의 전체 표현을 넣을 수 있습니다 :

#define cast(from, to) _Generic((from), \ 
    short:  (short) (to),   \ 
    char:  (char) (to),   \ 
    char*:  (char*) (to),   \ 
    default:  (void*) (to)) 

int main (void) { 
    short a = cast(a, 1); 

    return 0; 
} 
3

아니요, 불가능합니다. (이제 누군가가 나에게 잘못을 증명 조심해!)를 _Generic 표현에서

, 각 일반적인-협회 중 하나

형 이름입니다 : 할당 표현

또는

default : 할당 표현

형식 이름이나 형식 이름으로 확장 할 수 없습니다. 특히 _Generic 표현식이 컴파일 타임에 해결되었지만 이 아니고 매크로입니다. 최종 결과는 항상 표현식입니다.

그리고 표준 C.

+0

그것은 내가 두려워했던 것입니다! 아 글쎄, 그게 내가 1979 년보다 앞서있을 거라고 생각해서 얻은거야. :) – cat

+0

@cat 1979은 그걸로는별로 관련이 없다. 오래되었거나 새로운 언어가 부분 표현을 허용하지 않습니다. 이것은'int x =;'가 작동하지 않는 것과 같은 이유로 작동하지 않습니다. 완전한 표현식이 아닙니다. – Lundin

+0

@Lundin 나는 "진짜"응용 프로그램을 위해 주로 호모 이서 닉 언어 (예 : LISP)를 사용합니다. 따라서 C와 같은 언어에서 다른 표현식과 같은 느낌을주는 구문 요소는 그렇지 못하다는 사실에 항상 충격을줍니다. – cat