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 自身にさえキャスト出来ない。やはりこれはバグです。
|