2

次のコードがあります(簡略化):

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Unit1 in 'Unit1.pas';

var
  f: TFoo<Integer>;
begin
  f := TFoo<Integer>.Create;
  f.Baz;
  Readln;
end.


unit Unit1;

{$D-}

interface

type
  TFoo = class
  public
    procedure Bar(const s: string);
  end;

  TFoo<T> = class(TFoo)
  public
    procedure Baz;
  end;

implementation

uses
  TypInfo;

{ TFoo }

procedure TFoo.Bar(const s: string);
begin
  Writeln(s);
end;

{ TFoo<T> }

procedure TFoo<T>.Baz;
begin
  Bar(PTypeInfo(TypeInfo(T)).Name);
end;

end.

ステップインすると、そのユニットのデバッグ情報を明示的に無効にしましたが、どちらが正しいかステップf.BazインUnit1.TFoo<T>.Bazできませんでした。TFoo.Barこれは、ジェネリックが内部でどのように実装されているか (テンプレートなど) と、TFoo<Integer>が my で定義されているためだと思いProject1ます。次のユニットを追加すると、Bazもうステップインできなくなります。

unit Unit2;

{$D-}

interface

uses
  Unit1;

type
  TIntegerFoo = TFoo<Integer>;

implementation

end.

ジェネリック型のデバッグ情報を完全に削除して、その型をどこでも (デバッグ情報がオンになっている) 特殊化できますが、ジェネリック型のメソッドにステップインしないようにする方法はありますか? Generics.Collections.TList<T>「use debug .dcus」オプションを有効にしないとメソッドをステップ実行できないため、可能であるに違いないと思います。

4

1 に答える 1

3

少し実験した後、デバッグ情報を有効にするかどうかの決定は、型の特定のインスタンス化を参照する最初のユニットによって制御されるようです。

そのため、コンパイラが初めて型のインスタンス化に遭遇した場合、デバッグ情報が有効になり、特定の型がデバッグ情報でコンパイルされます。一方、最初のインスタンス化がデバッグ情報のないユニットにある場合、デバッグ情報はありません。

あなたの例では、最初の (そして唯一の) インスタンス化TFoo<Integer>は、デバッグ情報が有効になっている .dpr ファイルにあります。したがって、 を{$D-}.dpr ファイルに移動して に設定{$D+}するとUnit1、 のデバッグ情報がないことがわかりますTFoo<Integer>.Baz

最初のインスタンス化について説明する理由は、インスタンス化するさまざまなユニットが多数存在する可能性があるためTFoo<Integer>です。コンパイラが最初に遭遇するものは、インスタンス化された型がデバッグ情報でコンパイルされているかどうかを決定するものです。

TFoo<Integer>デバッグ情報を持たないようにすることも可能TFoo<string>です。


「use debug .dcus」オプションを有効にしないと Generics.Collections.TList メソッドをステップ実行できないため、可能であるに違いないと思います。

私はそれを説明することはできません。私の仮説によると、クラスを初めてインスタンス化するときにデバッグ情報がオンになっている場合、デバッグ情報は TList のインスタンス化で利用できるはずです。

デバッガーにバグがあるのではないかと思います。たとえば、次のプログラムを作成しました。

{$APPTYPE CONSOLE}
uses
  Generics.Collections;
begin
  TList<Integer>.Create.Add(6);
end.

Enable Debug DCUs をオフにしてこれを実行すると、確かにGenerics.Collections. しかし、私は完全に間違った場所に足を踏み入れます。に着陸しTList<T>.Packます。

申し訳ありませんが、これ以上の洞察を提供することはできませんが、あなたの質問のこの側面には困惑しています。

于 2012-12-11T13:21:49.300 に答える