フォーラム


ゲスト  

ようこそ ゲスト さん。このフォーラムに投稿するには 登録が必要です。

ページ: [1]
トピック: 解題『Delphiプログラマを見分ける10の質問。』
Owl's perspective
メンバー
投稿数: 24
解題『Delphiプログラマを見分ける10の質問。』
on: 2016/07/21 01:26 Thu

おなじみLynaさんから『Delphiプログラマを見分ける10の質問。』http://d.hatena.ne.jp/tales/20160718/1468814709というお題をいただいたのですが、
あまりの難易度の高さにみんなビビってしまって回答が付きそうもない状態のため、こちらの場をお借りしてみんなで考えてみよう、という企画です。
まずは上記の記事をご覧いただいた上で、意見をつけていただくなり、大喜利を始めるなり、割と自由な感じでいきたいと思います。

(追記)許可をいただきましたので問題を再掲します。
1.「const」と「var、out」の違いを参照という観点でひとつ挙げよ。またその違いを無くすためにはどうすれば良いか説明せよ。
2.文字列や動的配列などの型は自動で初期化されるため自分でnil等を代入する必要がないが、初めての使用時にnilや空文字列で初期化されていない場合があるのはどんな時か?またその理由を説明せよ。
3.複数の文字列変数を連結するとき、「sA := s1 + s2; sB := s3 + s4; s := sA + sB;」と「s := s1 + s2 + s3 + s4;」は足し算の数だけ見れば等価だが、後者の方が良いのは何故か。
4.nilが代入されているインスタンスの(クラスメソッドではない)メソッドを呼び出そうとした場合でも読み取り違反などのエラーが発生しないのは主にどんな状況か?またその理由を説明せよ。
5.関数内関数をコールバックを必要とする関数の引数として渡そうとすると「ローカル手続き/関数を手続き変数に代入しました」というエラーが発生してコンパイルできないが、これを回避するにはどうすれば良いか。またその際気を付けることは何か。
6.TComponent.FOwnerをはじめ、10 SeattleではWeak属性が指定されていたフィールドが10.1 BerlinではUnsafe属性に置き換えられているが、これはどういった理由が考えられるか。
7.recordでインターフェース(例えばIInterface)を実装する方法を簡単に説明せよ。
8.通常inlineが指定された関数・メソッドは処理内容がインライン展開可能な条件であれば呼び出しはインライン展開されるが、呼び出し方によってインライン展開される場合とされない場合が発生するのはどのような状況か述べよ。複数あればなお良い。
9.デフォルトのコンパイラ指令下において、RTTIでメソッド情報がほとんど取得できないのはどんな型か。またほとんどと書いたが、メソッドに関するどんな情報なら取得可能か。
10.無名メソッド型の実態はInvokeメソッドを持つインターフェースであり、通常はAnonMethod()のようにそのまま実行できるが、Invokeメソッドを明示的に呼び出さないと実行できない場合がある。どんな時か。

それではご自由にどうぞ。

DEKO
管理者
投稿数: 2691
Re: 解題『Delphiプログラマを見分ける10の質問。』
on: 2016/07/21 01:33 Thu

真っ当な設計をしてたら出会わない挙動が多く、ネタとしてわざと難しい質問にしてるので、
間違ったら恥ずかしいなんて躊躇せず、ぜひとも勢いよく突っ込んで爆発四散してください!

 
…との事 (^^;A

Owl's perspective
メンバー
投稿数: 24
Re: 解題『Delphiプログラマを見分ける10の質問。』
on: 2016/07/21 02:13 Thu

さてネタ振りだけでもアレなので。

1.のconstとvar/outの違いの話ですが、前提としてこれらの修飾の意味はパラメータの型によりだいたい3つくらいに分かれます。
まず単純型で、この場合はconstはメソッド内で値を変更できないというだけの意味(他はconst/var/outのいずれもつかないものと同じ)で、var/outは参照が渡されてメソッド内での書き換えが許される、というものです。
次にレコード型で、constは参照渡しかつメソッド内で書き換えを許さないというもので、var/outは参照渡しで書き換えを許す、となります。またconst/var/outのいずれもないと値渡し、つまりレコード型のコピーが作られてメソッドに渡されます。
3番目は文字列型で、constはメソッド内で値の変更を許さない代わりに文字列型の参照カウントをインクリメント/デクリメントせずその分パフォーマンスが多少向上します。var/outは文字列型変数そのものの参照を渡し、参照カウントが1の状態でメソッド内での書き換えを許します。

クラス型はポインタなので、アドレスを値で渡すという意味で単純型と同様になります。またインタフェース型は_AddRef/_Releaseにより参照カウントの管理が行われるということを除けばクラス型と同様、だと思いますが、これは試したことがないので間違っているかもしれません。

ということで前半の問いは
constは必要に応じてメソッド内で変更不可な参照が渡され、var/outは必ずメソッド内で変更可能な参照が渡される
あたりかなぁと思うのですが、後半は…う~ん。

Owl's perspective
メンバー
投稿数: 24
Re: 解題『Delphiプログラマを見分ける10の質問。』
on: 2016/07/21 10:57 Thu

つづいて4.のnilになってるインスタンスでAVとならない条件ですが、逆にAVとなる状況を考えてみます。

var
Foo: TFoo;
begin
Foo := nil;
Foo.Bar(Baz);

でBar呼び出しがエラーになる、と考えるとその理由には
(a)Barの呼び出し先の解決、つまり実行時に呼び出し先が決まる仮想(virtual)/動的(dynamic)メソッドを呼び出そうとしてインスタンスのVMT
http://docwiki.embarcadero.com/RADStudio/Berlin/ja/%E5%86%85%E9%83%A8%E3%83%87%E3%83%BC%E3%82%BF%E5%BD%A2%E5%BC%8F#.E3.82.AF.E3.83.A9.E3.82.B9.E5.9E.8B
を見にいこうとしてnilを参照してAV
(b)Barの中でSelfに属するフィールドを参照しようとしてAV
の2つが想定できます。

ということは問題に戻ると、(i)メソッドが静的でかつ内部で仮想/動的メソッドを直接、間接に呼び出しておらず、(ii)同様に直接、間接にインスタンスフィールドを参照していないこと、の両方を満たす、が条件ではないかと。

DEKO
管理者
投稿数: 2691
Re: 解題『Delphiプログラマを見分ける10の質問。』
on: 2016/07/21 11:08 Thu

3. について、あてずっぽうで。

「コピーが生成されるから」 かな?デバッグで CPU ウィンドウ見ればいいのでしょうけれど…。

Owl's perspective
メンバー
投稿数: 24
Re: 解題『Delphiプログラマを見分ける10の質問。』
on: 2016/07/24 15:27 Sun

3.の文字列の連結の件ですけど、これは複数の文字列をまとめて連結するときはコンパイラマジックにより
System._UStrCatNの呼び出し1回に変換されるから、そしてその内部では結果を格納する領域を一発で
確保するから、でしょうか。

Owl's perspective
メンバー
投稿数: 24
Re: 解題『Delphiプログラマを見分ける10の質問。』
on: 2016/07/24 21:27 Sun

と我々ボンクラがオタオタしているうちにLynaさんから回答が

Delphiプログラマを見分ける10の質問(解説編)。 – 全力わはー
http://d.hatena.ne.jp/tales/20160724/1469351157

ページ: [1]
WP Forum Server by ForumPress | LucidCrew
バージョン: 1.7.5 ; ページロード: 0.037 sec.