現在、CppUnitを使用してC++で単体テストを作成しています。最近、CppUnitsマクロを使用して、特定のケースで例外がスローされることを確認する必要がありました。
CPPUNIT_ASSERT_THROW(
boost::get<FooClassInBoostVariant>(m_boostVariantFooOrBar),
boost::bad_get);
テストのコンパイル中の警告は私を驚かせました(VS2010では、他のコンパイラでも警告になります...):
warning C4127: conditional expression is constant
CppUnitのマクロ定義を調べたところ、次のことがわかりました。
do { \
bool cpputExceptionThrown_ = false; \
try { \
expression; \
} catch ( const ExceptionType & ) { \
cpputExceptionThrown_ = true; \
} \
\
if ( cpputExceptionThrown_ ) \
break; \
\
CPPUNIT_NS::Asserter::fail( \
"Expected exception: " #ExceptionType \
" not thrown.", \
CPPUNIT_SOURCELINE() ); \
} while ( false )
まあ、私はこれがどのように機能するかを完全に理解しています。falseのため、do whileループは1回だけ実行され、breakはAsserter :: fail()部分を実行しないために使用されます。しかし、なぜ彼らはこのようにそれをしているのですか?whileループのブレーク条件は明らかに常に「false」であるため、これは-もちろん-コンパイラの警告をトリガーします。しかし、これを行うためのよりエレガントな方法はありませんか?私は通常、警告なしのコンパイルの原則を順守しているので、これは本当に私を悩ませます。
だから私の質問は本当に、なぜ彼らはそれをこのように実装しなかったのかということです:
{ \
bool cpputExceptionThrown_ = false; \
try { \
expression; \
} catch ( const ExceptionType & ) { \
cpputExceptionThrown_ = true; \
} \
\
if ( !cpputExceptionThrown_ ) { \
CPPUNIT_NS::Asserter::fail( \
"Expected exception: " #ExceptionType \
" not thrown.", \
CPPUNIT_SOURCELINE() ); \
} \
}
前もって感謝します!
-ハンネス