The Delphi Bug List

Entry No.
582
コンパイラ - コンパイル出来ない
int64 型にキャストした変数で '代入できない左辺値です' が発生
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 N/A N/A N/A N/A Absent Absent Absent Absent Exists Exists Exists Exists Exists Exists
解説
Reported by Primoz Gabrijelcic
(reposted from borland.public.delphi.objectpascal)
古いコードを Delphi 5 でコンパイルしようとしていた時、Miha Remec と私は int64 の非互換性に遭遇しました。以下はこの問題が再現する最小版です。
これをコンパイルしてみて下さい:
{$A+,B-,C+,D+,E-,F-,G+,H+,I+,J+,K-,L+,M-,N+,O+,P+,Q-,R-,S-,T-,U-,V+,W-,X+,Y+,Z1}
program int64bug;
{$APPTYPE CONSOLE}
uses sysutils;

type
  Tbug = class
    field: int64;
    constructor Create;
  end;

{ Tbug }

constructor Tbug.Create;
begin
  inherited;
  Int64Rec(field).Lo := 0; // !!!
end;

begin
end.
マーク(!!!)を付けている行で、Delphi は '代入できない左辺値です' を報告します。このコードは D4 では完全に正しく動作し、私としてはこれは完全に妥当だと思います。だれか説明で私を啓発させられますか?
さらに興味深いこと: int64 型の単純なグローバル変数(またはローカル変数)の場合、コンパイラはうまく動作します。以下は正しくコンパイルされます。例:
{$A+,B-,C+,D+,E-,F-,G+,H+,I+,J+,K-,L+,M-,N+,O+,P+,Q-,R-,S-,T-,U-,V+,W-,X+,Y+,Z1}

program int64bug;
{$APPTYPE CONSOLE}
uses sysutils;

var
  global: int64;

begin
  Int64Rec(global).Lo := 0;
end.
ところが十分に複雑なキャストを行うと、結局コンパイラは止まってしまいます。以下のサンプルは正しく動作しません(同じエラー - 代入できない左辺値…):
{$A+,B-,C+,D+,E-,F-,G+,H+,I+,J+,K-,L+,M-,N+,O+,P+,Q-,R-,S-,T-,U-,V+,W-,X+,Y+,Z1}

program int64bug;
{$APPTYPE CONSOLE}
uses sysutils;

var
  global: int64;

begin
  Int64Rec(int64((@global)^)).Lo := 0;
end.
(Robert Lee による追加コメント) 私が前に遭遇したことの原因を解き明かしてくれました。正確に同じではありませんが、同じ回避方法を取りました。私もこの問題を調べまわりました。そして、例えば double (これも8バイト)は任意の好きなサイズの構造にキャストすることが出来るのに、int64 は出来ないというのもとても奇妙に思えます。私は、あなたはこれも奇妙だと感じると思います
TSomeClass=class
  Data:int64;
  ...
end;

...
  int64(Data):=3;
  
'代入できない左辺値です' !!! int64 自身にさえキャスト出来ない。やはりこれはバグです。
Latest update of this entry: 2002-04-05
本家 The Delphi Bug List のエントリーはこちら
The Delphi Bug List 日本語訳 へ