エラー、バグ、質問 - ページ 1681

 
Karputov Vladimir:
名言が行きでも立ちでも変わりはないのです。インジケータで条件prev_calculate=0を制御する必要があります - これは歴史の交換と2番目のポイント - 変更されたバーの再計算のスペアモード、それは実際にはレート_合計です -prev_calculate +1。

返信する前に書いてあることを読むべき。デバッガーのバグを再現するコード!それを再現するためのデータはすべて与えられています。

以下は、同じバグを再現するスクリプトです。

int Func(){ return(0); }

int Func2()
{
//  return(0); // если расскоментировать и здесь поставить точку останова, то отладчик отработает, как надо  
  return(Func()); // здесь поставить точку останова (F9)
}

void OnStart()
{
  Func2();
}
 
fxsaber:
書いてあることを読んでから答えるべき。デバッガーのバグを再現するコード!再生に必要なデータはすべて与えられています。

私はあなたに答えました - あなたはOnCalculateが 何回呼び出さ れるかを気にしないことです。あなたの仕事は、rates_total、prev_calculate、prev_calculate==0の時の条件の2つの値を分析することによって、インジケータの完全または部分的な再計算を提供することです。

OnCalculate()は1回または2回呼び出されなければならないという厳密な条件はない。OnCalculate()は誰にも借りを作らない。しかし、プログラマは、rates_total、prev_calculate、prev_calculate==0のときの条件という2つの値を制御しなければならない。

 
Karputov Vladimir:
だから、OnCalculateが 何回呼ばれてもいいって言ったじゃないですか。あなたの仕事は、rates_total、prev_calculate、prev_calculate==0の時の条件の2つの値を分析し、インジケータの完全または部分的な再計算を提供することです。

デバッガが何回呼ばれるか、OnCalculateが何回呼ばれるかを気にしています。元々AWESOMEな人ですからねー。そして、すべてを気にする。

問題の本質を理解せずに、何かを教えようとしている。もちろん、ありがとうございます。しかし、相手の話を聞き、耳を傾けよう。

 
fxsaber:

いや、今はRTSで動かしてるよ、コチルが立ってる時に。デバッガは1回呼ばれると、2回呼ばれたように表示するという嘘をつくことが分かりました。プレイするためのコード(ティックが進行していないキャラクターで実行する)

F5を押した後、ブレークポイントにヒットします。そして、F5を2回目押した後 - 同様に。これは、確認として - すべきではありませんが、コードのその行を短縮し、それで試すことができます。

そうすることで、何が問題なのかが見えてくるのです。第1停止と第2停止でのiの値に注目する。

int Func(int& i)
{
        i++;
        return 0;
}

int OnCalculate( const int rates_total,
                 const int prev_calculated,
                 const datetime &time[],
                 const double &open[],
                 const double &high[],
                 const double &low[],
                 const double &close[],
                 const long &tick_volume[],
                 const long &volume[],
                 const int &spread[] )
{
        int i = 1;
        return(Func(i)); // здесь поставить точку останова (F9)
}
 
Sergei Vladimirov:

こうすることで、何が問題なのかを知ることができるのです。第1停止と第2停止でi値をトレースする。

それをトレースしたのが、この記事を書いた理由です。

1回呼ばれているのに、デバッガが2回呼ばれているように表示しているのは嘘だとわかりました。

F5キーを2回押すと、デバッガが同じ場所に戻ってしまうのはなぜですか?return(0)ではそのようなことは起こらないので、正しいです。

 

これは嘘ではなく、括弧付きの式を計算する前と、計算した後のreturnの直前の2回停止しているのです。

ちなみに、私見ですが、とても便利なトリックだと思います。覚えておかないといけない。終了前に戻り値を確認するために、括弧内の結果を別の変数に入れる必要はなく、デバッガ自体が再び停止します。

 
Sergei Vladimirov:

これは嘘ではなく、括弧付きの式を計算する前と、計算した後のreturnの直前の2回停止しているのです。

ちなみに、私見ですが、とても便利なトリックだと思います。覚えておかないといけない。終了前に戻り値を確認するために、括弧内の結果を別の変数に入れる必要はなく、デバッガ自体が2回目の停止を します。

これは便利だと納得します。しかし、デバッガで変数を指定せずに終了前の戻り結果を調べるにはどうしたらよいのでしょうか?
 
fxsaber:


このようなコードを入れてください。

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   int i=1;
   Print("Перед: i ",i,",rates_total ",rates_total,", prev_calculated ",prev_calculated);
   int rezult=Func(i);
   Print("После: i ",i,",rates_total ",rates_total,", prev_calculated ",prev_calculated);
   return(rezult); // здесь поставить точку останова (F9)
  }

をクリックし、インジケータをチャートに 表示させます。そして、ターミナルをリロードしてください(チャートからインジケータを削除する必要はありません)。OnCalculate()が1回、2回、3回と呼び出されることがあるのがわかると思います。つまり、上でも言ったように、厳密なルールはないのです。

 
Karputov Vladimir:

このようなコードを入れてください。

をクリックし、インジケータをチャートに 表示させます。そして、ターミナルをリロードしてください(チャートからインジケータを削除する必要はありません)。OnCalculate()が1回、2回、3回と呼び出されることがあるのがわかると思います。つまり、上でも言ったように、厳密なルールはないのです。

相手の書いたものを全く聞く気がないような文句を強要するんですね。
 
fxsaber:
これは便利だと納得します。しかし、デバッガで変数を指定せずに終了前の戻り結果を調べるにはどうしたらいいでしょうか?

Func()のボディを見て、終了する前に何を返すかを確認します。特殊なケースを想定しての話です。値が直接括弧で計算される場合は、もちろんダメです。

PS.とはいえ...なぜダメなのか?2番目の停止位置で、すべての引数return()を調べ、結果を計算します。)