I do not understand why the gnu C compiler uses 2 different macros with almost similar names -- __PTRDIFF_TYPE__
and ptrdiff_t
-- , as time as they
ptrdiff_t
is not a macro, it is a typedef name, defined by stddef.h
. It is specified in the C standard as the type of the difference between two pointers.
__PTRDIFF_TYPE__
is an implementation detail of GCC's stddef.h
. You should not use it unless you are writing a C runtime library.
The reason both exist is that the C compiler is not allowed to define ptrdiff_t
unconditionally. That name only acquires its standard-specified meaning if you include stddef.h
; it's available for application use otherwise. (Note that unlike C++, in C the standard library headers are not allowed to [behave as-if they] include each other.) __PTRDIFF_TYPE__
, on the other hand, is a name that the compiler is allowed to define unconditionally, because it begins with two underscores. So __PTRDIFF_TYPE__
is predefined unconditionally, and stddef.h
uses it to define ptrdiff_t
when appropriate.
And the reason stddef.h
goes through this indirection, rather than having a bare
typedef long int ptrdiff_t; /* or whatever */
is because the definition might need to vary depending on compilation mode. For instance, on x86-64/Linux, ptrdiff_t
is long int
in the default mode but int
in -m32
mode. The compiler has to know which integer type to use for the difference of two pointers, so it may as well expose that information rather than making stddef.h
repeat all the same logic.
(The GCC documentation you cited is quite clear on this, provided you read the entire paragraph:
These macros are defined to the correct underlying types for [a bunch of standard-specified typedef names]. They exist to make the standard header files
stddef.h
,stdint.h
, andwchar.h
work correctly. You should not use these macros directly; instead, include the appropriate headers and use the typedefs.
Emphasis mine.)