C99 如何在没有 _Generic (C11) 的情况下键入泛型宏?

How did C99 do type generic macros without _Generic (C11)?

在查看 tgmath.hsqrt 函数时,
我看到有一个 C99 的泛型宏。

我知道如何使用 Generic selection
来实现它 但是 _Generic 直到 C11 才存在。

我们有 C89 和 C99 的遗留项目。
如果可能的话,我想以类似的方式实现类型泛型功能。

如何在没有泛型选择的情况下用 C 编写类型泛型宏?

How did C99 do type generic macros without _Generic (C11)?

Non-portably.

在 C11 之前的 C 中没有编写 type-generic 宏的通用方法。

例如,如果您查看作为 glibc 的一部分提供的 tgmath.h header,它不会使用 _Generic(因为它需要使用不支持的编译器不支持 _Generic)。相反,它使用了许多 gcc-specific 功能,例如 __builtin_classify_type 包裹在一些非凡的宏中。文件顶部附近的评论说:

/* This is ugly but unless gcc gets appropriate builtins we have to do        
   something like this.  Don't ask how it works.  */

一些宏定义比较 sizeof (Val)(其中 Val 是宏参数)与 sizeof (double)。如果 floatdoublelong double 并非都具有不同的大小,这可能会失败。

整个东西都包裹在:

#if __GNUC_PREREQ (2, 7)
/* a lot of ugly macro definitions */
#else
# error "Unsupported compiler; you cannot use <tgmath.h>"
#endif

您可能可以使用 sizeof 将一些东西放在一起,但它会很难看。

您是否有机会使用支持 C11 或至少支持 _Generic 功能的编译器来编译遗留代码?