我在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 。
是否有任何技术禁止用户直接调用该函数,只允许他使用宏调用它?
答案 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)()
一样调用它。