1

Visual Studio 2012 を使用して、このサンプル コードをコンパイルしています。

#include <stdarg.h>
#include <stdio.h>

const char * __cdecl foo(const char * format, const char * requiredArgument, ...)
{
    va_list args;
    va_start(args, format);
    vprintf(format, args);
    va_end(args);
    return requiredArgument;
}

int main(int, char **)
{
    foo("The %s is %d pixels wide and %d pixels high.", "box", 300, 200);
    return 0;
}

プログラムのデバッグ ビルドは、「ボックスは幅 300 ピクセル、高さ 200 ピクセルです。」というメッセージを出力した後、正常に終了します。

リリース ビルドがセグメンテーション違反でクラッシュします。

この動作についての私の解釈 -しかし、私はそれについて間違っているかもしれません. 間違っている場合va_startva_start(args, requiredArgument)修正しva_start(args, format)てください.したいです。言い換えれば、私はva_startプログラム全体の流れを予測不能にする方法で誤用しているので、ここではセグメンテーション違反は問題ありません。

私の仮定が正しければ、2 つの質問があります。

  • va_start他のものを選択することが明らかに違法であるのに、正式に宣言された最後の関数パラメータを で指定する必要があるのはなぜですか?

  • うるさい VC++ コンパイラが、このように簡単に検出でき、潜在的に重大な落とし穴に対して警告を発しないのはなぜですか?

4

1 に答える 1

2

正式に宣言された最後の関数パラメータを va_start で指定する必要があるのはなぜですか?

そのマクロは最後の引数のアドレスを知る必要があるためです。

うるさい VC++ コンパイラが、このように簡単に検出でき、潜在的に重大な落とし穴に対して警告を発しないのはなぜですか?

それは十分に「賢い」だけではないからです。または、その作成者はこの警告を含めないことにしました。または、可能かもしれませんが、デフォルトではオフになっており、コンパイラフラグを使用してオンにすることができます。

于 2013-02-03T15:29:20.583 に答える