我有一个基于此处答案的模式,它适用于 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':
#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-ish 结构,它比清理和返回代码的粗鲁 goto 更有条理。使用这个 ONCE 宏而不是 while(0) 会关闭 VS。