只允许使用宏调用函数

时间:2013-04-11 13:46:34

标签: c

我在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

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

2 个答案:

答案 0 :(得分: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(...)

当然,如果某人有足够的心情绕过你,并且不关心疯狂的疣从他们的代码中解脱出来,那就是他们的问题。如果他们为您工作或与您一起工作,那么当您使用代码审查等外部因素来阻止此行为时。

答案 1 :(得分: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)()一样调用它。