c - C : make function visible and callable through macro only (MSVC compiler) 中的函数可见性

标签 c macros

我想让函数仅通过宏可调用(例如公开)给库的其余部分,以防止意外的不良副作用。

为什么?这是因为我有一个可变参数函数,可以从另一个可变参数函数调用,这样我想使用宏将 NULL 标记添加到调用中,从而使访问 va_list 更容易并防止未定义的行为。还有其他方便的场景,这可能真的很有帮助。

一个例子:

测试.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)

测试.c

//Implementation of the _func function
static void _func(char *dummy, ...) {
     //body goes here...
}

ma​​in.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 中甚至可能吗?

最佳答案

你可以用宏隐藏函数:

void _func(char *dummy, ...);
#define _func(...) error_use_the_macro_func_instead_of_calling__func_directly

// Always use the macro "func" instead of calling "_func" directly.
#define func(dummy, ...) (_func)(dummy, __VA_ARGS__, NULL)

注意 _func 两边的括号在宏中。这可以防止 _func免于被识别为类似函数的宏,并为宏提供对该函数的访问权限。如果有人试图调用 _func直接,他们得到

error C2065: 'error_use_the_macro_func_instead_of_calling__func_directly': undeclared identifier

这种“宏阴影”技术的优点是可以在表达式上下文中使用:

for (int i = 0; i < 5; func("incrementing i", ++i)) { ... }

或者如果我们稍微改变一下情况并给出 _func一个返回值:

int _func(char *dummy, ...);
#define _func(...) error_use_the_macro_func_instead_of_calling__func_directly

// Always use the macro "func" instead of calling "_func" directly.
#define func(dummy, ...) (_func)(dummy, __VA_ARGS__, NULL)

然后这允许你做类似的事情

int i = func("hello", 2) * func("there", 3);

关于c - C : make function visible and callable through macro only (MSVC compiler) 中的函数可见性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45358258/

相关文章:

编译器过度优化导致数据运行时和调试不一致

c - 需要左值作为递增操作数

c - 在 IDE 上运行良好,但在提交时出现运行时错误(SIGSEGV)

c - 这是宏滥用吗?

c++ - 可变参数宏 : how to solve "too many actual parameters for macro.."

c - SDL:在多线程程序中这样做安全吗?

c - 有没有更简单的方法在 Mac OS X 上键入和编译 C?

gcc - GCC ARM 汇编宏中的表达式

c++ - 为什么在C++宏上扩展为注释时会出现 “Expected a declaration”错误?

c - 有没有办法将多个值作为 C 中定义的单个宏值传递给宏函数?