2011-12-22 11 views
2

私は今までに見たことのない奇妙な問題を抱えてきました。今私は、forループを持っている:ループに入ることができません

var 
a,counter: byte; 
begin 
    a:=0; 
    for counter := 1 to 10 do//I put a breakpoint at this line 
    begin 
    a:=a*5; 
    a:=a+counter; 
    end; 
end; 

私は上記の行にブレークポイントを入れて、私はそれを行うことができないループにステップインしようとします。デバッガはすぐにループを処理し、end.Inに行く私は正しい結果を得るが、私はループをステップバイステップで追跡することはできません。これは単なる例であり、実際の仕事ではありません。私はちょうどいつこれが起こるのかを知りたいですか?私は間違いなくループのすべてのステップを追跡することを覚えています。私はDelphi 2010で働いています。

+1

最適化コンパイラを忘れてしまった。あなたのコードは何もしません。 –

+1

'結局のところ私は正しい結果を得ることができますが、ループを段階的に進めることはできません。'あなたは= 3051755を得ると言っていますか?このコードがすべて最適化されていれば、私はそれが信じがたいことが分かります。 – Johan

+0

@Johan、投稿されたコードには「結果」はありません。コードは決して実行されません。これは実際のコードではありません(質問の最後の段落でそう言います)。 –

答えて

10

ループ内の両方のコード行を完全に最適化することができます。ループの外にはaで何もしないので、両方の割り当ては不要です。最適化の後、コンパイラは、実際に

for counter := 1 to 10 do 
    ; 

を残しているあなたがそこにブレークポイントを持っていなかった場合、それは何もしないよう、ループは、同様に削除されます。

コードに問題があり、上記の情報が役立たない場合(ループ実行後に変数aを使用)、実際のコードを投稿する必要があります。この作成されたコードは非常に分かりやすく分析できます。あなたの実際のコードの問題は、この単純な、またははるかに複雑な分析することができます。

+0

ループが扱うものはすべてプロシージャ自体にのみスコープされた変数なので、 "ループは何もしません"という意味ですか? –

+0

いいえ、何もしないのでループは何もしません。コードを読むと、 'a'に値 '5'が割り当てられ、直ちに' a'( '5')+' counter'の現在の値が割り当てられ、ループが再び実行され、同じプロセスが繰り返されます。だから、すべてのループは値を 'a'に代入し、割り当てられた各値を直ちに破棄します。ループ内で意味のあることは何もないので、ループを実行する理由はありません。 –

+0

@KenWhite、私はループの後にaが使われていないので、ループは役に立たないと理解できます。しかし、ループ内での計算は後で使用されると無意味ではありません。 1,7,38,194..etcはループ反復の結果の値です。 –

7

最適化をオフにすると、プロジェクトオプションで差異が生じます - >コンパイル - >コード生成を参照してください。

+2

私はしばしば、デバッグ中に最適化をオフにして、コンパイラによって既に最適化された変数の値を取得できるようにします。 –

+0

私はこの場合に役立つとは思わない。ポストされたコードは最適化の有無にかかわらず絶対に無意味であり、それをコンパイルする理由もない。おそらく必要ではない。それは 'NOP'です。 –

+1

OPは、コードは実際のものではなく単なる例であると書いています。私の答えは、通常、この種の問題は最適化によるものであることを指摘することです。スイッチをオフにして、その無意味なループにもステップすることができるはずです... – ain

3

Kenの答えに対するコメントで、Mikayilはコードが手順の中にあることを暗示しました。 これは、コードを見ても当然の前提です。 Mikayil、可能なループにノーステッピングによって観察されるように - 結果:上の

Procedure Test; 
var 
    a,counter: byte; 
begin 
    a:=0; 
    for counter := 1 to 10 do//I put a breakpoint at this line 
    begin 
    a:=a*5; 
    a:=a+counter; 
    end; 
end; 

begin 
    Test; 
end. 

設定の最適化:私たちはこのようなテストを設定あれば

最適化をオフに設定:結果 - ループ内でステッピングすることができます。

ケンの答えにあるMikayilの質問: ループに入ることができないかどうかは、aのローカルスコープであったかどうかを検討します。

ケンはありません答えたが、これはそうではありません。今では最適化がオンまたはオフであるかどうかは関係ありません

var 
    a : byte; // scope of a is outside of the procedure 

Procedure Test; 
var 
    counter: byte; 
begin 
    a:=0; 
    for counter := 1 to 10 do//I put a breakpoint at this line 
    begin 
    a:=a*5; 
    a:=a+counter; 
    end; 
end; 

begin 
    Test; 
end. 

、ループに足を踏み入れることは、とにかく可能です。

だから、彼の答えでは絶対的に正しいです。

更新(XE2でテスト):

  1. セットの最適化オフ:ループにステッピング可能にするため

    3つの可能性があります。

  2. ローカルスコープ外にaを宣言してください。
  3. ループの後にaを使用してダミー演算を挿入します。Like:if (a < counter) then;

これらの手順のいずれも、珍しいデバッグ手順ではありません。

+0

私はKenのコメントを「スコープではなく、「a」が使用されていない」と読みました。ループの後に 'a'を使用すると、 'a'がローカルであっても、割り当てが最適化されないため、スコープが原因ではありません。コンパイラは、テストケースを最適化しません。なぜなら、 'a'が他の場所で使用されているかどうかを調べることがないからです。 –

+0

私はそうでしたし、私はそのことに関して意見の相違はありません。しかし、フォローアップの問題は、「a」のローカルスコープがループを踏み外すことができなかったかどうかであった。さらに、Kenは、オン/オフの最適化はループに入ることができないこととは何の関係もないことを示唆しています。これは正しくありません。 –

+0

@ MC9000では、DelphiはVSとは関係ありません。コンパイラは、状態変化を持続させないループを最適化することができます。ループ内のプロシージャー呼び出しは、コンパイラーがループを最適化するのを妨げる可能性が非常に高いでしょう。 –

関連する問題