4

次のC/C++コード用

void fun(int* x)
{
    //SOMECODE;//WITHOUT SAVING PREVIOUS VALUE
    if(SOME CONDITION)
    printf("VALUE OF X IS DIFFERENT THAN PREVIOUS CALL \n");
}

int main()
{
    int a;
    a=9;
    fun(&a);
    a=12;
    fun(&a);
    return 0;
}

変数が変更されるかどうかに関する情報を提供する関数またはフラグ値はありますか?解決策がある場合は、返信してください

4

4 に答える 4

5

関数への「最後の」呼び出し中にパラメーターを保存するための追加のコードを提供しないと、同じ値で呼び出されたか、別の値で呼び出されたかを検出する機会がまったくありません。

xの「現在の」値はスタックにのみ存在するため、関数呼び出しが終了すると完全に失われます。

マルチスレッド化以前の時代には、関数の最後の実行中に静的変数を使用して x の値をキャッシュするだけで、func(ほぼ) 問題を解決できたはずです。

void fun (int x) {
    static int old_value = VALUE_INVALID;

    if(x != old_value)
       printf("VALUE OF X IS DIFFERENT THAN PREVIOUS CALL \n");

    old_value = x;
}

このアプローチにまだ残っている唯一の問題は、再入可能性です。つまりfunc、シグナル ハンドラーで呼び出された場合、キャッシュされた値が台無しになる可能性があります。

マルチスレッドアプリケーションで実行している場合、このアプローチを使用するときに何らかのロック メカニズムを追加で提供する必要があります。

関数の「最後の」呼び出しと「実行中」の値が正確に何を意味するのかを明確にする必要があるため、おそらくこのシナリオではめちゃくちゃになるでしょう。

現在の正しい値は、スレッド B の前に func に入ってまだ実行中のスレッド A の値ですか、それとも B の後に入って func の実行が既に終了しているスレッド B の値ですか?

于 2013-03-18T17:27:57.147 に答える
2

質問をもう一度読むと、変数が変更されるかどうかを確認するのではなく、同じ字句識別子の2 つの異なるインスタンスが異なるかどうかを確認しています。

これは、明示的な比較以外では不可能です。


変数の変更の検出に関する元の回答:

移植可能な標準 C または C++ では方法がありません。

ただし、変数がいつ変更されたかを検出する環境固有の方法があります。MMU アクセス制御フラグを (mprotectまたは経由でVirtualProtect) 使用して、最初の書き込みで例外を生成し、ハンドラー内からダーティ フラグを設定できます。(最近のほぼすべての OS は、ディスクに書き戻す必要があるかどうかを調べるために、メモリ マップト ファイルでこれを行います)。または、ハードウェア ブレークポイントを使用して、そのアドレスへの書き込みを一致させることができます (デバッガーはこれを使用して、変数にブレークポイントを実装します)。

これらのどれも、古い値と比較するほど効率的ではありません。(ただし、古い値と比較すると、ABA シナリオが失われます)

于 2013-03-18T17:04:38.883 に答える
1

現在の値が最後の呼び出しで送信された値と異なるかどうかを確認する可能性はありません。

実行時に を呼び出すたびにfun()、独自の のコピーを持つ独立したスタック フレームが作成されますxfun()後で呼び出すために、このスタック フレーム (ローカル変数を格納するために使用される) 内に値を保存することはできません。

また、「変数が以前の値と比較せずに値を変更した」かどうかを判断する方法もありません。

于 2013-03-18T17:07:02.147 に答える
0

変数が変更されるかどうかをチェックする目的は何ですか?

変数とフラグを含む構造体を使用するのはどうですか。variable が変更されると、フラグが設定され、 struct が function に渡されます。関数内のフラグをテストして、変数が変更されているかどうかを確認します。

于 2013-03-18T18:08:33.903 に答える