0

次のヘルパー関数があります。

inline void DebugMessage(const TCHAR* fmtstr, ...)
{
        va_list args;
        va_start(args, fmtstr);

        TCHAR buffer[256];
        StringCbVPrintf(buffer, 256, fmtstr, args);
        OutputDebugString(buffer);

        va_end(args);
}

そして、私はそれを次のように2回呼び出します:

DebugMessage(_T("Test %d\n", 1)); // incorrectly closed _T()
DebugMessage(_T("Test %d\n"), 1); // correctly closed _T()

次の出力が得られます。

Test 0
Test 1

2番目のケースは期待どおりに機能します。エラーではなく、最初のケースが機能する理由がわかりません。

4

1 に答える 1

3

_Tは関数ではなく、(Unicode ビルドで) に展開されるマクロですL ## x。括弧の位置が間違っていてもコンパイル エラーは発生しません。行のどの部分がマクロによって消費されるかが変わるだけです。

マクロは 1 つのパラメーター ( x) しかとらないため、最初のケースでは、クロージャーが正しくない場合、2 番目のパラメーター ( 1) は単純に破棄され、出力で得られる数値は単にスタック上のランダム データの結果になります。

デフォルトでは、VS 2012 はこれに関する C4002 警告 (マクロの実際のパラメーターが多すぎる) を発行することに注意してください。そのため、警告が適切に有効になっていることを確認することをお勧めします。

于 2013-09-03T03:02:25.927 に答える