다른 사람들이 말했듯이, 이것에 대한 좋은 일반적인 해결책은 없습니다. 유형 이름은 전처리기에 표시되지 않으므로 #ifdef
을 사용하여 유형 이름을 테스트 할 수 없습니다.
그러나 부분적인 솔루션에는 여러 가지가 있으며, 해당 유형에 대한 요구 사항의 출처에 따라 다릅니다.
1990 년, 1999 년 및 2011 년에 발행 된 ISO C 표준의 여러 버전이 있습니다.각각의 새로운 표준 (이론적으로)은 이전의 표준을 대체하고 대체하며, 각각은 새로운 유형을 정의합니다. 예를 들어 1999 C 표준은 <stdbool.h>
과 <stdint.h>
과 bool
, int32_t
등의 헤더를 추가했습니다. bool
유형을 사용하려고하지만 C99을 지원하지 않는 구현으로 이식 가능한 코드를 원한다면 같은 :
#if defined(__STDC__) && __STDC_VERSION__ >= 199901L
#include <stdbool.h>
#else
typedef enum { false, true } bool;
#endif
enum
유형이 같은 정확히을 작동하지 않습니다 C99의 내장 bool
유형, 당신은 당신이 그것을 사용하는 방법에 약간의 조심해야하므로.
유형 uintptr_t
은 <stdint.h>
으로 정의됩니다. 그것은 정보의 손실없이 변환 된 void*
포인터 값을 보유 할 수있는 부호없는 유형입니다. 그러한 부호없는 타입을 가지지 않는 구현체 (예를 들어, 포인터가 어떤 정수형보다 크므로)는 그것을 제공하지 않을 것입니다. 직접 유형 자체에 대한 테스트 할 수 없습니다,하지만 당신은 그 경계를주는 매크로 테스트 할 수 있습니다
#include <stdint.h>
#ifdef UINTMAX_MAX
/* uintmax_t exists */
#else
/* uintmax_t doesn't exist */
#endif
당신은 C99을지지 않습니다 경우 __STDC__
및 __STDC_VERSION__
에 대한 시험이 포장해야 할 수도 있습니다 또는 더 나은.
유형 long long
은 C99에 추가 된 사전 정의 된 유형 (라이브러리의 일부가 아님)입니다. 다시 말하지만, 당신은 직접 테스트 할 수는 없지만 그 경계를 정의하는 매크로 테스트 할 수 있습니다
#include <limits.h>
#ifdef LLONG_MAX
/* long long exists */
#else
/* long long *probably* doesn't exist */
#endif
마지막으로, 당신은 C에서 직접 할 수없는 일이 있습니다,하지만 당신은 같이 할 수있는 프로그램의 빌드 프로세스의 일부. 예를 들어, POSIX는 POSIX 특정 헤더 <unistd.h>
에 pid_t
유형을 정의합니다 (이것은 getpid()
함수에 의해 리턴 된 프로세스 ID 유형입니다). 당신은 조건부 헤더를 포함 할 수 없습니다 -하지만 당신은 헤더가 존재하지 않는 경우 컴파일에 실패하는 작은 프로그램을 작성할 수 있습니다
#include <unistd.h>
pid_t dummy;
이 빌드 프로세스의 일환으로,이 파일을 컴파일하려고합니다. 성공할 경우 구성 헤더에
#define HAVE_PID_T
과 같은 줄을 추가하십시오. 실패하면, 당신은 다음과 같이 쓸 수 있습니다, 소스 코드에서
#undef HAVE_PID_T
같은 라인을 추가합니다
#include "config.h"
#ifdef HAVE_PID_T
#include <unistd.h>
/* pid_t exists */
#else
/* pid_t doesn't exist */
#endif
GNU Autoconf 테스트 이런 종류의 자동화하는 방법을 제공합니다,하지만 비판 됐어요 지나치게 복잡하고 다루기 힘들다.
이 모든 것은 유형이 존재하는지 여부를 결정한 후에 해당 정보로 유용하게 사용할 수 있다고 가정합니다. bool
과 같은 일부 유형의 경우 거의 동일한 대안을 구현할 수 있습니다. 반면에 pid_t
의 경우 프로세스를 처리하는 모든 코드를 #ifdef
으로 설정하지 않으면 좋은 대체 수단이 될 수 없습니다. 프로그램이 pid_t
과 getpid()
이없는 시스템에서 작동하지 않는다면, 존재한다고 가정하는 코드를 작성하는 것이 가장 좋습니다. 코드를 제공하지 않는 시스템에서 코드를 컴파일하려고하면 컴파일이 즉시 실패하고 이것이 가능한 최선의 방법 일 수 있습니다.
특별한 경우. stddef.h를 포함 시키면 항상 ptrdiff_t를 정의해야합니다. –
특정 정의의 존재 및 특성을 코드에서 테스트 할 수있는 것을 "반영"이라고합니다. 스크립팅 언어는 스크립팅 언어가 비교적 쉽기 때문에 전체 반영을 지원하는 경향이 있습니다. .NET과 JVM도 리플렉션을 지원합니다. 그러나 모국어의 경우 런타임 리플렉션을 지원하려면 많은 추가 실행 코드가 필요합니다. 일부 컴파일 타임 리플렉션은 오버 헤드없이 지원 될 수 있지만 C는 컴파일시에도 사실상 반사 지원을하지 않습니다. – Steve314
cmake 또는 autotools와 같은 도구 사용 – szx