更新时间:2023-12-01 08:42:34
通常不需要重命名宏包装函数,因为在宏扩展内,宏的名称不会扩展.
There's normally no need to rename macro-wrapped functions because inside the expansion of a macro, the macro's name is not expanded.
这是直接来自C11标准的示例:
Here's an example straight from the C11 standard:
#define cbrt(X) _Generic((X), \
long double: cbrtl, \
default: cbrt, \
float: cbrtf \
)(X)
当然,如果您具有#include <tgmath.h>
,则会遇到问题,因为在这种情况下,您已经具有类型通用的宏,例如上面的宏,并且您将无法重新定义sqrt
(除非您#undef
它).而且必须先#include <math.h>
定义该宏.
Of course, you'll run into problems if you've #include <tgmath.h>
because in that case you'll already have type-generic macros, such as the above, and you won't be able to redefine sqrt
(unless you #undef
it). And you must #include <math.h>
before defining that macro.
即使如此,您还是要踩在薄冰上.该标准保留了标准库函数的名称,并坚持认为(§ 7.1.3/2):
Even so, you're treading on thin ice. The standard reserves the names of standard library functions, and insists that (§7.1.3/2):
如果程序在保留它的上下文中声明或定义标识符(而不是7.1.4允许),或者将保留标识符定义为宏名,则行为未定义.
If the program declares or defines an identifier in a context in which it is reserved (other than as allowed by 7.1.4), or defines a reserved identifier as a macro name, the behavior is undefined.
参考的第7.1.4节确实允许您#undef
一个类似于函数的宏,该宏遮盖了标准库函数,但是对我来说尚不清楚您是否可以随后重新定义它. YMMV.
The referenced section 7.1.4 does allow you to #undef
a function-like macro which shadows a standard-library function, but it is not clear to me that you are allowed to subsequently redefine it. YMMV.
如果您想使用_Generic
来调用包装函数,则仍然可以在不重命名原始函数的情况下使它起作用.例如:
If you wanted to use _Generic
to call a wrapper function, you can still make that work without renaming the original function. For example:
#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);
}