2

我正在用 C 开发自己的断言函数,并在我的头文件中声明为:

void Certify_Continuity( const char* expression, const int line, const char* file );

应该使用定义为的宏调用它:

#if !defined ( ENABLE_DEBUG ) || defined ( __CALLE__ )
#define DEBUG_ASSERT( e ) (void)(e)
#else
#define DEBUG_ASSERT( e ) ( e ) ? (void)0 : Certify_Continuity( #e, __LINE__, __FILE__ )
#endif

这里的问题是程序员可以直接调用Certify_Continuity

是否有任何技术不允许用户直接调用该函数,只允许他使用宏调用它?

4

2 回答 2

5

宏只是在编译器正确运行之前执行的文本(令牌)替换,因此您不能阻止某人只是手动扩展宏并删除他们不喜欢的部分。

但是,您可以使某人这样做变得任意困难和危险。例如,您可以省略Certify_Continuity头文件中的声明,并像这样将其声明为内联:

#define DEBUG_ASSERT(e) do { \
    extern void Certify_Continuity( const char* expression, const int line, const char* file ); \
    if(!(e)) Certify_Continuity(#e, __LINE__, __FILE__); \
} while(0)

这样,任何直接调用函数的人都必须先声明原型。

您还可以以其他人会三思而后行的方式命名它:

void DO_NOT_CALL__USE_DEBUG_ASSERT__Certify_Continuity(...)

当然,如果有人有足够的决心绕过你,并且不关心他们代码中的疯狂疣,那么这就是他们的问题。如果他们为您工作或与您并肩工作,那么您就可以使用代码审查等外部因素来阻止这种行为。

于 2013-04-11T13:59:23.127 回答
3

您可以使用 C 中(foo)()调用函数的技巧foo,同时foo()扩展宏foo(假设两者都存在)。

在您的情况下,您的宏应如下所示:

#if !defined ( ENABLE_DEBUG ) || defined ( __CALLE__ )
#define DEBUG_ASSERT( e ) (void)(e)
#else
#define DEBUG_ASSERT( e ) ( e ) ? (void)0 : (Certify_Continuity)( #e, __LINE__, __FILE__ )
#endif
#define Certify_Continuity(x,y,z) YOU_SHOULD_NOT_CALL_Certify_Continuity()

如果用户尝试Certify_Continuity直接调用,则会发出一个YOU_SHOULD_NOT_CALL_Certify_Continuity不存在的错误。

当然,这并不能阻止用户像(Certify_Continuity)().

于 2013-04-11T14:03:49.497 回答