まーだ「C/C++のポインタの機能--変数の場所(アドレス)」がらみだったりする*1けど、まー、一般的な話題とも言えるかな。
「C/C++のポインタの機能--変数の場所(アドレス)」(修正済み部分)に:
呼び出し元の変数を変更する「参照呼出し」という機能
という記述があります。この表現も変なのか、それとも正しいのか、僕には判断できません。そもそも「参照呼(び)出し」って言葉がよくわからんのよ。で、参照呼び出しについて詮索してみます。
アドレスを渡すこと、呼び側をいじること
概念的な話じゃなくてメカニズムを問題にしましょう。手続きの引数はスタック(の活動レコード)に積まれるとします。スタック上の引数領域に格納されているのがアドレスで、そのアドレスの指す所にデータ実体があるときに参照呼び出しっていうのでしょうかね?
では、アドレスで指された先にあるデータ実体をそっくりスタックにコピーしたらどうでしょう。何か差がでますか? arg->field と arg.field と書き方が変わるなんてのはどうでもいいことです。
もし、引数のデータ実体を一切いじらないなら、アドレスを積んでもデータ実体を積んでも別に変わりないですよね。「いじらない」じゃなくて「いじれない」データ、つまりイミュータブル・データに関して言えば、アドレスを積む方式とデータ実体を積む方式は本質的な差がありません。いやっ、構文やら気分やらは違いますよ、でも、「だからどうした」って差でしょ、それ。
となるとやはり、呼ばれた手続きが呼び側の環境をいじれるかどうか? ってことでしょうか。呼び側データ(ヒープのデータも含む)が呼ばれ側スタックへそっくりコピーされて渡されれば、呼び側への影響は無理です。一方、スタックにはアドレスが渡される方式なら、手続き内でアドレスの先をいじれますね。よって、参照呼び出しってのは、「呼び側へ影響を与えられる形で手続きを呼び出すこと」かな?
うーん、なんかおかしいぞ。「呼び側へ影響を与える」ための引数は出力引数といえばいいんじゃないの(変な言葉だけど>出力引数)。呼び側へ影響を与えるために参照を渡すなら、参照渡しは手段でしょう。手段を示して目的を暗示するのは分かりにくいから嫌い。
「参照呼び出し」なんて言う必要はないのでは
- スタックに積んだ引数(の低水準のセマンティクス)がアドレスであること
- 呼ばれた側から呼び側の環境を変更可能であること
さー、どっちが参照呼び出しでしょう。はたまた、どっちでもないのでしょうか。
(1)は、「引数がポインターだ」とか言えば済むこと。(2)は「出力引数を持つ」でもいいでしょ。結局、意味不明の「参照呼び出し」なんて言葉をわざわざ使う必要性/必然性はどこにも見つからないなぁ。(1)でも(2)でもないもっと深遠な意味があるなら教えてくださいよ、どなたか。
それと、値呼び出し(call by value)と対<つい>になるのは、参照呼び出し(call by reference)よりむしろ名前呼び出し(call by name)みたいだし。
*1:この話題、なーんかすごーく興味を引かれてしまった。このウキウキ感は?(不明)