通常不需要重命名宏包装函数,因为在宏的扩展内部,宏的名称不会扩展。
这是直接来自 C11 标准的示例:
#define cbrt(X) _Generic((X), \
long double: cbrtl, \
default: cbrt, \
float: cbrtf \
)(X)
当然,如果你这样做,你就会遇到问题#include <tgmath.h>
因为在这种情况下,您已经拥有类型通用宏,例如上面的宏,并且您将无法重新定义sqrt
(除非你#undef
它)。而且你必须#include <math.h>
在定义该宏之前。
即便如此,你仍如履薄冰。该标准保留了标准库函数的名称,并坚持(§7.1.3/2):
如果程序在保留标识符的上下文中声明或定义标识符(7.1.4 允许的除外),或者将保留标识符定义为宏名称,则行为未定义。
引用的第 7.1.4 节确实允许您#undef
一个类似于函数的宏,它隐藏了标准库函数,但我不清楚您是否可以随后重新定义它。 YMMV。
如果你想使用_Generic
要调用包装函数,您仍然可以在不重命名原始函数的情况下使其工作。例如:
#include <nanny.h>
/* In this file, you can't call nanny(char), and if you call it
* with an unsigned argument, we'll insert an additional check
*/
#define nanny(X) _Generic((X), int: nanny, unsigned:nanny_wrapper)(X)
int nanny_wrapper(unsigned x) {
assert(x < INT_MAX);
/* The redundant parentheses prevent macro expansion */
return (nanny)(x);
}