C预处理器中的类型检查

Typechecking in C preprocessor

我希望通过使用宏来设置基于变量类型的函数来在 c 中实现可选参数。

#define dostuff(BOOL) dostuffwithbool(BOOL)
#define dostuff(INT) dostuffwithint(INT)

这种事情有可能吗? (即使我知道它可能不是)。我会接受任何答案,无论多长或多hacky。

预处理器本身无法处理 C 类型,因为宏在程序标记化后展开,但解析了 C 语言的 before 语法结构。

根据您的应用程序,您可以使用 C11 提供的 _Generic。它基本上是 switch-case over types.

#define dostuff(val)                    \
  _Generic((val), bool: dostuffwithbool \
                , int:  dostuffwithint) (val)

请注意,如果 dostuffwithbool/dostuffwithint 是 function-like 宏,则此解决方案将不起作用。由于宏后面缺少 (,因此不会扩展宏。

你不能只用宏本身来完成它,因为宏是一个占位符(对于预处理器)而不是一个函数(子例程)。

预处理器用您在宏定义中定义的代码替换所有出现的宏。它与 #define PI 3.141592654 等数字定义相同。这里,PI 而不是 变量。相反,代码中每次出现的 PI 都将替换为 3.141592654。宏的计数相同。

例如,这段代码带有一个简单的比较宏:

#include <stdio.h>

#define EQUALS(a, b) (a == b ? 1 : 0)

int main()
{
    char nZero = 0;
    char nOne = 1;
    printf("0 is 0: %d\n", EQUALS(nZero, nZero));
    printf("0 is 1: %d\n", EQUALS(nZero, nOne));
    return 0;
}

将被预处理器扩展为以下代码:

int main()
{
    char nZero = 0;
    char nOne = 1;
    printf("0 is 0: %d\n", (nZero == nZero ? 1 : 0));
    printf("0 is 1: %d\n", (nZero == nOne ? 1 : 0));
    return 0;
}

注意:小心使用宏,因为它们将完全按照您在定义中编写它们的方式展开。因此,例如,将计算放在括号中是一种很好的做法,因为这样的事情:

#define ADD(a, b) a + b
int x = a * ADD(b, c);

将扩展为:

int x = a * b + c;

不是这个:

int x = a * (b + c);