我想拥有可以包含可选参数的函数.当然这不能用C来完成,但它有可能带有一些宏观魔力:
#define _macroWith1Arg(_0, _1, macroName, ...) _ ## macroName
#define _macroWith2Args(_0, _1, _2, macroName, ...) _ ## macroName
#define _macroWith3Args(_0, _1, _2, _3, macroName, ...) _ ## macroName
#define macroWith1Arg(macroName, ...) _macroWith1Arg(_0, __VA_ARGS__, macroName ## _1, macroName ## _0)(__VA_ARGS__)
#define macroWith2Args(macroName, ...) _macroWith2Args(_0, __VA_ARGS__, macroName ## _2, macroName ## _1, macroName ## _0)(__VA_ARGS__)
#define macroWith3Args(macroName, ...) _macroWith3Args(_0, __VA_ARGS__, macroName ## _3, macroName ## _2, macroName ## _1, macroName ## _0)(__VA_ARGS__)
#define _sum_1(_1) (_1)
#define _sum_2(_1, _2) (_1) + (_2)
#define sum(...) macroWith2Args(sum, __VA_ARGS__)
fprintf(stderr, "%d ", sum(1)); // Prints 1
fprintf(stderr, "%d ", sum(1, 2)); // Prints 3
Run Code Online (Sandbox Code Playgroud)
我喜欢它的外观:它看起来像一个带有可选参数的普通函数.但这样做的缺点是你不能拥有一个像宏一样的函数指针sum.所以我听说你应该将名称大写以将其显式标记为宏(如"SUM")以避免混淆.
现在我的问题是:这个命名约定是否真的有必要,我的意思是标准C用它来做errno(例如至少在我的平台上)?我认为大多数IDE都可以识别宏并将其突出显示.我真的很想听听你对此的看法.
编辑:
我找到了一种方法来实现,你可以采取一个函数指针:
int my_sum(int, int);
#define _sum_1(_1) my_sum(_1, 0)
#define _sum_2(_1, _2) my_sum(_1, _2)
#define sum(...) macroWith2Args(sum, __VA_ARGS__)
int (*sum)(int, int) = my_sum;
// Use it as a "function":
fprintf(stderr, "%d ", sum(1, 2)); // Prints 3
// Take a function pointer:
int (*sumptr)(int, int) = sum;
fprintf(stderr, "%d ", sumptr(1, 0)); // Prints 1
Run Code Online (Sandbox Code Playgroud)
在C(预处理器是其中的一部分)中,您可以比编辑中建议的更多:宏和函数可以具有相同的名称.虽然在应用程序代码中很少这样做,但C库本身可以拥有它.这里标准函数可以作为宏实现,但是也必须提供具有相同名称的符号.
因此标准本身并不遵守宏名称应该全部大写的规则.
我认为,如果你在实施中小心谨慎
那么使用小写标识符应该没有问题.
通过这个你确保
并且在你所有的实现中表现得好像你的宏在哪里有一个函数.
顺便说一句,您发布的代码不符合标准.以下划线开头的标识符保留在文件范围中.这不是惯例,而是必要的.