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);
我希望通过使用宏来设置基于变量类型的函数来在 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);