gpt4 book ai didi

c - C 中的命名宏有限制/问题吗?

转载 作者:行者123 更新时间:2023-12-04 11:37:39 25 4
gpt4 key购买 nike

我想要有可以有可选参数的函数。当然,这不能用 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

我喜欢它的样子:它看起来像一个带有可选参数的普通函数。但这样做的缺点是您不能拥有指向宏的函数指针,如 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

最佳答案

在 C 中(预处理器是其中的一部分)您可以做的比您在编辑中建议的还要多:宏和函数可以具有相同的名称。虽然这很少在应用程序代码中完成,但 C 库本身可以做到这一点。这里可以将标准函数实现为宏,但也必须提供一个同名的符号。

因此标准本身并不遵守宏名称应全部大写的规则。

我认为如果您在实现过程中小心谨慎

  • 用全套参数调用宏就是预处理器阶段的身份
  • 提供了同名的有效函数声明

那么使用小写标识符应该没有问题。

这样你就可以确保

  • 为你的函数重复原型(prototype)仍然是一个有效的操作
  • 获取函数指针可以毫无问题地完成

并且在您的所有实现中,您的行为就好像您的宏是一个函数。

顺便说一句,您发布的代码不符合标准。以下划线开头的标识符在文件范围内保留。这不是惯例,而是强制性的。

关于c - C 中的命名宏有限制/问题吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26217029/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com