我认为这可能更接近你想要的,但我不确定。我的理解是允许具有任意数量参数的 c 函数,这些参数经过类型检查并且可以在编译时消除。
让我通过引用标准来警告您在标识符中使用下划线。您可能会遇到保留的标识符。但是,我不知道这种可能性。
ISO/IEC 9899:1999 (E) 7.1.3
— 以下划线和大写字母或另一个下划线开头的所有标识符始终保留用于任何用途。
此解决方案需要 GCC。GCC 的版本还必须支持弱符号。这个想法是允许编译器使用弱符号查找正确的函数定义。此外,通过使用编译器应该修剪死分支的知识来简化函数的内容,即:
if (0) { ... }
在编译时无需进一步分析(GCC 4.x 肯定会这样做)。通过将不存在的可选参数定义为 c 预处理器 (cpp) 符号,您可以避免在函数体中包含 cpp 条件(如果需要)。请参阅下面如何为 f_opt0 定义 opt1 和 opt2。
#include <assert.h>
#include <stdio.h>
extern void f_opt0(int a, int b) __attribute__((weak));
extern void f_opt1(int a, int b, int opt1) __attribute__((weak));
extern void f_opt2(int a, int b, int opt1, int opt2) __attribute__((weak));
#ifdef OPT0
void f_opt0(int a, int b) {
#define opt1 0
#define opt2 0
#endif
#ifdef OPT1
void f_opt1(int a, int b, int opt1) {
#define opt2 0
#endif
#ifdef OPT2
void f_opt2(int a, int b, int opt1, int opt2) {
#endif
if (opt1) printf("opt1=%d\n", opt1);
if (opt2) printf("opt2=%d\n", opt2);
printf("a+b=%d\n", a+b);
#undef opt1
#undef opt2
}
#define f(a, b, o1, o2) \
if (f_opt2) f_opt2(a, b, o1, o2); \
else if (f_opt1) f_opt1(a, b, o1); \
else if (f_opt0) f_opt0(a, b); \
else { assert(0 && "no f() defined!"); }
int main(void) {
f(1, 2, 1, 1);
return 0;
}
我的测试非常有限,我不提倡这是 C 语言中的良好设计。它似乎容易出现问题并且难以理解。但是,我希望它可以解决您的目标。