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 <firstname.lastname@example.org> Joseph S. Myers <email@example.com>
* 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.