How can I check a certain type is already defined in C compiler?

There's no way to do that in general. In some cases there may be a macro that is defined at the same time as the type that you can use.

In your particular example, you can #include <stddef.h>, which should always define ptrdiff_t.


As others have said, there is no good general solution to this. Type names are not visible to the preprocessor, so you can't use #ifdef to test for their existence.

There are a number of partial solutions, though, and they vary depending on where the requirements for a given type came from.

There are several versions of the ISO C standard, issued in 1990, 1999, and 2011. Each new standard (in theory) supersedes and replaces the previous one, and each one defines some new types. For example the 1999 C standard added headers <stdbool.h> and <stdint.h>, and types bool, int32_t, etc. If you want to use the bool type, but still want your code to be portable to implementations that don't support C99, you can do something like:

#if defined(__STDC__) && __STDC_VERSION__ >= 199901L
#include <stdbool.h>
#else
typedef enum { false, true } bool;
#endif

The enum type doesn't behave exactly like C99's built-in bool type, so you need to be a little careful in how you use it.

The type uintptr_t, defined in <stdint.h> is optional. It's an unsigned type that can hold a converted void* pointer value without loss of information; an implementation that has no such unsigned type (say, because pointers are bigger than any integer type) won't provide it. You can't directly test for the type itself, but you can test for the macros that give its bounds:

#include <stdint.h>

#ifdef UINTMAX_MAX
/* uintmax_t exists */
#else
/* uintmax_t doesn't exist */
#endif

You may need to wrap this in a test for __STDC__ and __STDC_VERSION__ if you can't assume C99 or better.

The type long long is a predefined type (not part of the library), added in C99. Again, you can't test for it directly, but you can test for the macros that define its bounds:

#include <limits.h>

#ifdef LLONG_MAX
/* long long exists */
#else
/* long long *probably* doesn't exist */
#endif

Finally, there are things you can't do directly in C, but that you can do as part of your program's build process. For example, POSIX defines a type pid_t in the POSIX-specific header <unistd.h> (it's the type of a process identifier, returned by the getpid() function). You can't conditionally include a header -- but you can write a small program that will fail to compile if the header doesn't exist:

#include <unistd.h>
pid_t dummy;

As part of your build process, try to compile this file. If it succeeds, append a line like

#define HAVE_PID_T

to a configuration header; if it fails, append a line like

#undef HAVE_PID_T

In your source code, you can then write something like:

#include "config.h"
#ifdef HAVE_PID_T
#include <unistd.h>
/* pid_t exists */
#else
/* pid_t doesn't exist */
#endif

GNU Autoconf provides a way to automate this kind of test, but it's been criticized for being overly complex and unwieldy.

All of this assumes that, once you've determined whether a type exists, you can do something useful with that information. For some types, like bool, you can implement a nearly equivalent alternative. For pid_t, on the other hand, there likely isn't a good fallback, unless you simply #ifdef out all the code that deals with processes. If your program just isn't going to work on a system that doesn't have pid_t and getpid(), it might be best to just write code that assumes they exist. If you try to compile your code on a system that doesn't provide them, it will immediately fail to compile, and that may be the best thing you can do.