The Delphi Bug List

Entry No.
451
コンパイラ - コンパイル出来ない
小さいオブジェクトを返す関数が誤ったコンパイルエラーを生成する
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
Absent Exists Exists Exists Exists Exists Exists Exists Exists Exists Exists Exists Exists Exists Exists
解説
Reported by Bjorn Sahlen; checked by Reinier Sterkenburg
以下のコードはエラーメッセージ("変数が必要です")を生成します。object のサイズを増やす(n > 4)にするとエラーは発生しなくなります。

これはバグです。なぜなら:

  • コンパイラがオブジェクトのサイズによって異なる動作をします。
  • ドット表記の代わりにwithステートメントを使用すると、コンパイラはこのコードを受け入れます(サンプルコード参照)。
  • コード補完機能はこの選択肢を提示します!
const  
  n = 4;           // 1〜4だとNG  >= 5ならOK !

type
  obj= object
    b: array [1..n]  of byte;
    procedure proc;
  end;

procedure obj.proc;
begin  end;

function func: obj;
begin  end;

var  x: byte;
begin
  x:= func.b[1];         // ok
  with func  do proc;    // ok
  func.proc;             // エラー: 変数が必要です !!!
end.
解決策 / 回避方法
私が受け入れられる唯一の回避方法は、objectの代わりにrecordと普通のfunctionやprocedureを使用する方法です。もうひとつの回避方法は当然ながら、オブジェクトのサイズを確実に5バイト以上にする事です。
ユーザーからのコメント
Chris R. Timmons
30 Jun 2001  10:08 PM GMT
バグではありません。バグがあるのはDelphiではなく、サンプルコードです。

バグ #1: 古いスタイルである "object" が使用されています。代わりに "class" を使用します:

type
obj = class(TObject)

バグ #2: 関数 "func" は obj のインスタンスを返していません。対象となるオブジェクトのインスタンスが存在しないのですから、サンプルの最後のコードは正常に動作しないはずです。func を変更します:

function func : obj;
begin
Result := obj.Create;
end;

この二つの修正により、Delphi 5.01 ではこのサンプルコードが正常に動作するようになります。
Jordan Russell
01 Jul 2001  07:06 PM GMT
申し訳ありませんがサンプルコードにバグはありません。古いスタイルのオブジェクトに対するあなたの理解がバグっています :)
Latest update of this entry: 2002-04-03
本家 The Delphi Bug List のエントリーはこちら
The Delphi Bug List 日本語訳 へ