-3

この質問には、バグがリリース ビルドでのみ現れる理由を説明する多くの優れた回答があります。
リリース バージョンのバグがデバッグ モードに存在しない一般的な理由
未定義の動作に関して、より具体的な質問があります。

プログラムがデバッグ ビルドでは常に正しく動作しているように見えても、リリース ビルドでは動作が異なる (ただし、常に同じように正しく動作しない) 場合、問題は未定義の動作が原因である可能性がありますか?

4

1 に答える 1

2

未定義の動作が原因でしょうか? もちろん。それは常に未定義の動作のためですか? 確かにそうではありません。

これを想像してください:

assert(scanf("%d", &n) == 1);

この行は、リリース モードで単純に削除されます。これは未定義の動作ではありませんが、プログラムが異なる方法で動作することは間違いありません。

assertここでは明らかな例かもしれませんが、次のより複雑な状況を考えてみてください。

#ifndef NDEBUG
# define DBG(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
#else
# define DBG(fmt, ...) ((void)0)
#endif

int shared_var;

static inline void do_something_fast(void)
{
    DBG("doing something fast\n");
    shared_var = something_fast();
}

スレッド1を持っています:

...
mutex_unlock();
local_var = shared_var;
...

およびスレッド 2:

...
mutex_lock();
do_something_fast();
...

この例はまったくばかげていますが、これらの線に沿ったものはマルチスレッド環境では非常に一般的です。この例では、次のようになります。

  • スレッド 1: mutex_unlock を呼び出し、スレッド 2 をウェイクアップしてスリープ状態にします
  • スレッド 2: do_something_fast() を呼び出します
    • リリース時: fprintf が呼び出され、スレッド 2 がスリープ状態になる
      • 現在、スレッド 1 は の古い値をコピーしshared_varますlocal_var
    • デバッグ中: スレッド 1 が上書きしますshared_var
      • スレッド 1 が の新しい値をコピーしshared_varますlocal_Var

ご覧のとおり、この例では I/O をブロックすることでスレッド間で特定の動作が強制され、それ自体はデバッグ モードでのみ有効になっていました。これは、デバッグで動作するプログラムが、リリース用にコンパイルされたときとは異なる動作をする可能性があることも意味します。

于 2012-10-20T22:06:31.333 に答える