我有一个基于这里的一个答案的模式,它可以在clang、gcc和MSVC上工作。我在这里发布它,希望它对他人有用,并因为这里的答案帮助了我构建它。
#ifdef WIN32
# define ONCE __pragma( warning(push) ) \
__pragma( warning(disable:4127) ) \
while( 0 ) \
__pragma( warning(pop) )
#else
# define ONCE while( 0 )
#endif
我是这样使用它的:
do {
// Some stuff
} ONCE;
您也可以在宏中使用此功能:
void SomeLogImpl( const char* filename, int line, ... );
#ifdef NDEBUG
# define LOG( ... )
#else
# define LOG( ... ) do { \
SomeLogImpl( __FILE__, __LINE__, __VA_ARGS__ ); \
} ONCE
#endif
如果 F 在函数中使用 'ONCE',那么上面指出的情况也适用:
This also works for the case pointed out above, if F uses 'ONCE' in a function:
#define F( x ) do { f(x); } ONCE
...
if (a==b) F(bar); else someFunc();
编辑:多年之后,我意识到我忘记了添加这个宏实际上是为了哪个模式而编写的 - “switch-like-a-goto”模式:
do {
begin_some_operation();
if( something_is_wrong ) {
break;
}
continue_big_operation();
if( another_failure_cond ) {
break;
}
finish_big_operation();
return SUCCESS;
} ONCE;
cleanup_the_mess();
return FAILURE;
这提供了一种类似于try/finally结构的构造,比混乱的goto清理和返回代码更加有结构性。使用这个ONCE宏而不是while(0)可以让VS安静下来。
#define
宏转换为内联函数是否可行?这样会更安全。 - Thomas Matthews