【发布时间】:2017-07-27 18:17:20
【问题描述】:
我想让函数只能通过宏调用(例如公开)到库的其余部分,以防止意外的不良副作用。
为什么?这是因为我有一个可变参数函数,可以从另一个可变参数函数调用它,这样我想使用宏将NULL sentinel 添加到调用中,从而更容易访问 va_list 并防止未定义的行为。还有其他方便的场景,这真的很有帮助。
一个例子:
test.h
void _func(char *dummy, ...);
//I would like to make sure that rest of the library
//only calls _func through this macro
#define func(dummy, ...) _func(dummy, __VA_ARGS__, NULL)
test.c
//Implementation of the _func function
static void _func(char *dummy, ...) {
//body goes here...
}
main.c
int main(int argc, char *argv[]) {
//This should not be allowed by compiler
_func("dummy", "arg1");
//This should be allowed by compiler, but since definition
//of _func is static in test.c file, compiler is not happy anyway
//LNK2001 unresolved external symbol __func
func("dummy", "arg1");
return 0;
}
我已经尝试使用#define 和#undef 编译器指令以某种方式强制这种情况,但无济于事。这在C语言中甚至可能吗?
【问题讨论】:
-
不幸的是,你不能真正做你想做的事,因为宏调用
func(...)将被_func(...)替换,如果_func不可用,那么它将不可用 no有什么关系。最佳解决方案 (IMO) 是记录需要NULL终止参数的函数,不提供它会导致未定义的行为。你已经有一些文档说它只会接受指针参数,对吧?然后只需使用终止符要求扩展该文档即可。 -
您的 _func 将不会在任何其他编译单元中可见,因为它被声明为
static。宏不是您可以“调用”的东西。您在 .h 文件中的函数定义与该函数本身不同,因此您将收到编译器错误。无论如何,您的想法完全没用(可能是因为您不知道预处理器是如何工作的以及静态的含义)。正如@Some程序员花花公子所写的那样-相信潜在用户,只需在头文件和文档中写下如何使用该功能的注释。他们必须信任您才能使用您的图书馆。 -
谢谢大家,我仍然会尝试使用下面的答案......现在。干杯!