답변
변수 유형 컴파일러로 알려져 있지만하지에 있습니다 .. func_int
내가 변수 유형은 컴파일 타임에 알려진대로,이에 대한 해결책이있을 수 있습니다 생각
에 int
, 파견 때 전처리 기 (코드를 단순히
구조화되지 않은 텍스트
토큰 스트림으로보고 단순한 대체 조작 만 수행함). 그래서 나는 당신이 C 매크로로 이것을 달성 할 수 없다는 것을 두려워한다.
C++에서는 이러한 문제를 해결하기 위해 템플릿을 발명했습니다.
** C **에서 해결 방법이 있습니까? – lexer
이것은 잘못된 결론입니다. 전처리 기는 * 컴파일러가 분석을 수행 할 수 있도록 매크로 확장을 정렬 할 수있는 경우 인수 유형을 알 필요가 없습니다. gnu 컴파일러에서이 문제를 해결하는 방법은 arnaud576875의 대답을 참조하십시오. 또한 전처리 기는 코드를 구조화되지 않은 텍스트로 보지 않고 중요한 토큰 스트림 *으로 간주합니다. –
매크로로는이 작업을 수행 할 수 없습니다. 매크로의 값은 컴파일시에 대체되며 intepreted되지 않습니다. 그것들은 단지 대용품입니다.
C1X으로 가능하지만 현재 표준에서는 가능하지 않습니다.
은 다음과 같이 표시됩니다 C89/ANSI C 시간 검사 유형을 실행 할 가능성이 없지만, 그것을 허용하는 지금 gcc 확장이
#define cbrt(X) _Generic((X), long double: cbrtl, \
default: cbrt, \
float: cbrtf)(X)
이 질문이 Google에서 처음으로 팝업됩니다. 이제 C11을 사용하여 가능합니다. http://en.cppreference.com/w/c/language/generic –
. typeof 또는 내가 기억한다면 그 줄을 따라 뭔가. 나는 리눅스 커널에서 그것을 한 번 보았다. kernel.h에서
:
#define min(x, y) ({ \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })
이 문서를 살펴 보자 내가 처음이 실제로 여기에 질문을보고 GCC hacks in the Linux kernel
을 SO에 대한 :
나는 당신이 당신의 문제를 해결하는 데 그것을 어떻게 사용하는지 정확히 모르겠지만, 티.
이것은 런타임 유형 검사가 아닙니다. C가 동적으로 입력되지 않았기 때문에 유형을 입력하십시오. 정보는 컴파일시에만 사용 가능하다. – Christoph
실제로 변수 유형은 컴파일시 알려지지 만 매크로 확장은 컴파일 전에 수행됩니다. 매크로 대신 2 개의 오버로드 된 함수를 구현하는 것이 좋습니다.
유형의 특성을 테스트 할 수 있습니다.
예를 들어 int
은 음수 값을 가질 수 있지만 char*
은 음수 값을 가질 수 없습니다. 그래서 ((typeof(param))-1) < 0
경우, param
은 서명되지 : 컴파일러는 분명히 이것을 최적화
if (((typeof(param))-1) < 0) {
do_something_with_int();
} else {
do_something_with_char_p();
}
.
여기를보십시오 : http://ideone.com/et0v1
이 유형은 다른 크기가 있다면 더 쉽게 될 것이다.
if (__builtin_types_compatible_p(typeof(param), int)) {
func_int(param);
} else if (__builtin_types_compatible_p(typeof(param), char*)) {
func_string(param);
}
것은 그것을 시도 :
if (sizeof(param) == sizeof(char)) {
/* ... */
} else if (sizeof(param) == sizeof(char16_t)) {
/* ... */
} else if (sizeof(param) == sizeof(char32_t)) {
/* ... */
} else {
assert("incompatible type" && 0);
}
GCC는 유형의 호환성을 확인 할 수있는 __builtin_types_compatible_p()
내장 기능을 가지고있다 : 다른 문자 크기를 처리 할 수있는 것보다 예를 들어, 당신이 원하는 경우에 일반적인 매크로를 작성하는 여기에 : http://ideone.com/lEmYE
당신이하려고하는 것을 달성하기 위해 매크로에 넣을 수 있습니다 :
#define FUNC(param) ({ \
if (__builtin_types_compatible_p(typeof(param), int)) { \
func_int(param); \
} else if (__builtin_types_compatible_p(typeof(param), char*)) { \
func_string(param); \
} \
})
(({...})
은 GCC's statement expression이며, 일련의 명령문은 rvalue가됩니다.
__builtin_choose_expr()
내장형은 컴파일 할 표현식을 선택할 수 있습니다.
#define FUNC(param) \
__builtin_choose_expr(__builtin_types_compatible_p(typeof(param), int) \
, func_int(param) \
, __builtin_choose_expr(__builtin_types_compatible_p(typeof(param), char*) \
, func_string(param) \
, /* The void expression results in a compile-time error \
when assigning the result to something. */ \
((void)0) \
) \
)
이 실제로에서 약간 변형 예이다 (이 경우 유효하지 않은 somehting를 컴파일) : PARAM의 유형이 모두 int
및 char*
와 호환성이없는 경우 __builtin_types_compatible_p으로이 컴파일시 오류를 트리거 할 수 있습니다 __builtin_choose_expr docs.
'func_int (x);','func_string (x);'모든 것을'do {} while (0)' –
원래 코드를 닫지 않았다. 'do {} while()'은 매크로가 아니기 때문에 ;-) – arnaud576875
-1'typeof'는 C가 아니라 gcc 확장자입니다. 주소에서 '부호'비트를 설정할 수 없다고 생각하는 이유는 무엇입니까? –
가능할지라도, 그것은 추한 것입니다. C는 그것을 위해 설계되지 않았습니다. 구조체와 공용체를 사용하면 런타임 디스패치도 그렇게 할 수 있습니다. –