The Delphi Bug List

Entry No.
556
コンパイラ - コンパイルされるべきではない
withステートメントを使用すると、読み取り専用プロパティに書き込めてしまう
1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 4.03 5.0 5.01 6.0 6.01 6.02 Kylix 1.0
N/A Exists Exists Exists Exists Exists Exists Exists Exists Exists Exists Exists Exists Exists Exists
解説
Reported by Michael Stratmann; checked by Reinier Sterkenburg
以下のコードを良く見てください:
あるユニットで以下のようにします:
type
  TMyRecord = record
    Field1: Integer;
  end;

  TMyClass = class
  private
    FRec: TMyRecord;
  public
    property Rec: TMyRecord read FRec;
  end;
別のユニット(またはプログラム)で以下のようにします:
var
  AnObj: TMyClass;
begin
  AnObj := TMyClass.Create;
  AnObj.Rec.Field1 := 1;       // コンパイルエラー: 代入できない左辺値です
  with AnObj.Rec
  do Field1 := 1;              // コンパイルが通ります
(Delphi 1 の場合、コンパイラの振る舞いは一貫しており、両方の代入文でエラー(無効な変数参照)が発生します)

最初の代入がコンパイル出来ないのに、with ステートメントを使った二つ目の代入がコンパイル出来てしまうのは奇妙(誤り)です。両方コンパイル出来るか、両方コンパイル出来ないか、どちらかであるべきです。
プロパティ Rec が object(class)の場合、両方ともコンパイルを通ります(そして静的オブジェクトの場合は record と同じ振る舞いをします)。
Latest update of this entry: 2002-02-28
本家 The Delphi Bug List のエントリーはこちら
The Delphi Bug List 日本語訳 へ