C99 adds "type-generic macros" in <tgmath.h>.
They feel much more like C++ than in the spirit of C, but
since they're in the standard glibc needs to implement them.
Implementing them needs compiler extensions; if you look
at the one glibc 2.1 installs you'll see macros using
__typeof__ and statement expressions that sort-of
work and sort-of make sense. However, they get the behavior
for integer arguments completely wrong.
The other day I studied the matter and decided that a
fully correct implementation was impossible with the existing
GCC features and proposed some new compiler builtins to
allow for a clean implementation. After a few mailing list
messages on how things might be achieved with other
extensions such as __builtin_classify_type, I saw
how it could in fact be implemented. The macros I produced
work, but are more obscure than even glibc's usual standard.
Now Ulrich Drepper has been crazy enough to include them
in glibc.
2000-08-01 Ulrich Drepper <drepper@redhat.com>
Joseph S. Myers <jsm28@cam.ac.uk>
* math/tgmath.h: Make standard compliant. Don't ask how.
/* This is ugly but unless gcc gets appropriate builtins we have to do
something like this. Don't ask how it works. */
/* 1 if 'type' is a floating type, 0 if 'type' is an integer type.
Allows for _Bool. Expands to an integer constant expression. */
#define __floating_type(type) (((type) 0.25) && ((type) 0.25 - 1))
/* The tgmath real type for T, where E is 0 if T is an integer type and
1 for a floating type. */
#define __tgmath_real_type_sub(T, E) \
__typeof__(*(0 ? (__typeof__(0 ? (double *)0 : (void *)(E)))0 \
: (__typeof__(0 ? (T *)0 : (void *)(!(E))))0))
/* The tgmath real type of EXPR. */
#define __tgmath_real_type(expr) \
__tgmath_real_type_sub(__typeof__(expr), __floating_type(__typeof__(expr)))
If __tgmath_read_type_sub makes sense to anyone
without referring to some version or draft of the standard,
I'd be surprised; the rules used for the type of
conditional expressions are arcane. If you try including
this header in C++ code, or try calling any of the macros
with complex integer types (a GCC extension), you'll get
what you deserve. If you try nesting calls to the
type-generic macros, it should work - provided your
machine can cope with the code expansion involved, similar
to the problem of a harmless five nested calls to strcpy
expanding to 200 Mbyte of text after preprocessing. If
you actually want to use such an obscure
<tgmath.h>, you trust too much in the
compiler and in magic.
You are in a maze of twisty macros, headers, compiler
extensions and expensive standards, all different.