私のおそらく決定論的なプログラムは、実行ごとにわずかに異なる出力の1つを生成します。入力、コンパイラ、およびコンピューターは変更されません。常に合理的に見えるため、どの出力が正しいかわかりません。
rand() への無駄な呼び出し以外に、どうしてこれが可能になるのでしょうか?
私のおそらく決定論的なプログラムは、実行ごとにわずかに異なる出力の1つを生成します。入力、コンパイラ、およびコンピューターは変更されません。常に合理的に見えるため、どの出力が正しいかわかりません。
rand() への無駄な呼び出し以外に、どうしてこれが可能になるのでしょうか?
いくつかの方法で:
もっと推測することはできますが、有意義な助けが必要な場合は、コードの関連部分を公開することをお勧めします:-)
出力がヒープに割り当てられたアドレスに依存する場合:
int main(int argc, char* argv[])
{
printf("%p", malloc(42));
return 0;
}
実行ごとに、malloc() は異なる仮想アドレスを返す場合があります。割り当てが失敗した場合は NULL は言うまでもありません。
かもしれない:
プログラムで float / double を使用している場合、一部のアーキテクチャでコンテキスト スイッチがあると、結果に違いが生じることがあります。
x86 では、FPU は中間結果に拡張精度を使用しますが、メモリに保存すると (プロセスまたはスレッドのいずれかのコンテキスト スイッチがある場合に発生します)、そのような精度は失われます。これにより、結果に多少の相違が生じる可能性があります (プログラムでそのような問題が検出されました)。この問題を回避する 1 つの方法は、浮動小数点演算に FPU ではなく SSE を使用するようにコンパイラーに依頼することです。
http://www.network-theory.co.uk/docs/gccintro/gccintro_70.html
rand() への迷子の呼び出しに加えて
rand()
同じ初期シードをフィードする限り、完全に決定論的です。
いくつかのコード (HINT HINT) を見なくても、私が考えることができる最善の方法は、パターンを探すことです。たぶん、日時固有の何か。
また、競合状態を探してみてください。それは非決定論的に見える可能性があります。
ポインタが指すものの代わりにポインタの値を使用すると、常に興味深い結果が得られます。
「外界」とあまりやり取りしないプログラムでは、非決定論の一般的な原因はポインター比較への依存です。ときどきコードでそれを目にすることがあります: 辞書式比較関数が比較対象を使い果たした場合 (すべてが等しい場合) 、最後の手段としてオブジェクトのアドレスを比較します。実際の割り当て場所はプラットフォームごと、実行ごとに異なる可能性があるため、オブジェクトが動的メモリに割り当てられている場合、これにより異なる順序が生成される可能性があります。
未定義の動作。つまり、出力の変更の考えられるすべての原因を説明するには、数百ページかかります。デバッグして変更が発生する場所を見つけるか、C++仕様を読んでみてください。
明らかに、月の満ち欠けのバグの新しいインスタンスです。
あなたは多くの情報を提供しませんでした。しかし、生計を立てるためにリアルタイム プログラミングを行っている者として、そのようなことが起こったときに私が探す最も可能性の高い犯人は次のとおりです。
たとえば、共有ライブラリが思ったほど「共有」されておらず、あるプロセスのハンドルを使用して、2 番目のプロセスでまだ初期化されていないテーブルにインデックスを付けようとしたときに、そのような問題が発生しました。物事がどのように開始されたかに応じて、まだ 3 番目のプロセスで重要なデータが破棄される可能性があります。