好き嫌いの類かもしれませんが・・・
type
TPtrHogeHoge=^THogeHoge;
THogeHoge=Record
Hoge1:Integer;
Hoge2:Integer;
end;
上記の宣言のとき、下記の関数のようにポインタで使用する場合
下記の(1)と(2)、どちらで記述しますか?
procedure aaa(PHoge: Pointer);
begin
//(1)
THogeHoge(PHoge^).Hoge1
//(2)
TPtrHogeHoge(PHoge)^.Hoge1
end;
TPtrHogeHogeの宣言が、あってもなくても、(1)なら通用します。
でも、この宣言がなければ、ローカルに宣言したり、
pHoge: ^THogeHoge
のように、変数を宣言して使うことになるでしょう。
そういった点を見ると、(1)は便利な記述になるのですが、
単なるPointer型を逆参照(でいいの?)すると、その型って何?
型無しのなにか?
それをキャストしてもいいの?
と、なんか、違和感があるんですよね。
それに、(2)よりもコストがかかりそうなイメージが・・・。
質問というよりアンケートみたいなものなので、興味があればレスください。
また、速度面で説明できる人がいたら、ぜひ解説をお願いしたいです。
一応、現環境は、Delphi5 です。
気になったら実際に時間を測定してみたらどうですか?
私は機械語を読むことはできないので、気になった時は時間を測ってます。
今回の場合は、ほぼ同じ値なのでマシン語レベルは同じだと思われます。
type
PHoge=^THoge;
THoge=Record
int:Integer;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i:Integer;
c:Cardinal;
p:Pointer;
begin
c:=GetTickCount;
new(p);
THoge(p^).int:=0;
for i := 0 to 100000000 do
//inc(THoge(p^).int);
inc(PHoge(p)^.int);
Caption:=IntToStr(GetTickCount-c);
end;
いあ、違う…
↑では動きません。
p:Pointerではなくp:pHogeなら同じになります。
new(p)のときにpのメモリサイズを確保してるんですね。
気づきませんでした。
new(PHoge(p));
はできるけど
new(^THoge(p));
はできないのでどのみちPHoge=^THoge;は必要そうです。
>単なるPointer型を逆参照(でいいの?)すると、その型って何?
>型無しのなにか?
>それをキャストしてもいいの?
この解釈は間違ってる。
THogeHoge(PHoge^).Hoge1
このように書くと、PHogeは型無しポインタではなく、TPtrHogeHoge型のポインタになる。
そうでなければコンパイルが通らない。
TPointer型は、すべてのポインタ型との代入互換性があるけど、型キャストせずに直接逆参照はできないということ。
TPtrHogeHoge=^THogeHoge;
このような宣言が必要なのは、引数として構造体のポインタ変数を
要求するWinAPIが多いからで、ポインタ変数が不要であるならば
キャストで済ませばいいと思う。
>THogeHoge(PHoge^).Hoge1
>TPtrHogeHoge(PHoge)^.Hoge1
CPUウィンドウを見れば、この二つは同じマシン語に変換されると
分かるんじゃないかな?
ツイート | ![]() |