質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Q&A

3回答

1601閲覧

「広義の参照渡し」とは何か?

raccy

総合スコア21735

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

2グッド

2クリップ

投稿2019/05/18 22:38

編集2019/05/19 14:08

C++、C#、PHP、VB.NET、Delphi(Object Pascal)、Swift、Rust等には「参照渡し」と言われる機能があります。

どれらも、英語では"pass by reference"という表現をしており、Microsoftやembarcaderoは「参照渡し」、PHP日本語訳チームは「リファレンス渡し」と訳しています。C++については、仕様書にそのまま"pass by reference"という言葉の解説はみつけられませんでしたが、n4659のp.855などで"~ be passed by reference"という表現が使われています。

上記のような言語では、"pass by reference"(英語圏では"call by reference"とも言われる場合がある)と言われる機能があります。私が解釈する限り、これらの機能は同一のものです。そして、その日本語訳として「参照渡し」というのは特におかしくないと思います。

さて、私が聞きたいのは、言語の機能として「参照渡し("pass by reference")」がある場合の話ではありません。言語の機能として「参照渡し」がない、少なくとも、英語の公式ドキュメントで"pass by reference"がない言語、ましてや、Pythonのように値渡しであると公式ドキュメントに書いてある言語において、「参照渡し」が意味する物が何であるのかと言うことです。これらを一部の人達は広義の意味での「参照渡し」と言っているようですので、以下、この質問では「広義の参照渡し」とし、前述のC++等での機能を「狭義の参照渡し」とします。(そういう言葉があるわけではありませんので、ご注意ください。この質問でのみの表現です。)つまり、聞きたいこと事は端的に言うと以下になります。

「広義の参照渡し」の定義は何ですか?

また、その定義から、C、Java、JavaScript、Python、Ruby、Groovy、Go、Haskell、Scala、Kotlin、R、Lua等の「狭義の参照渡し」が無い言語において「広義の参照渡し」とは具体的にどのような動作のことを指すのかの説明も加えていただければ幸いです。逆に「広義の参照渡し」すらない言語はどのような物があるのかも教えて頂くと助かります。

なお、回答では「広義の参照渡し」と「狭義の参照渡し」を区別していただくようお願いします。「区別することが不可能である」と考えているのであれば、単に「参照渡し」と書いても良いですが、その場合は、「区別することが不可能である」理由も添えて頂くと助かります。

「狭義の参照渡し」がある言語やない言語のリストは、私も全ての言語に詳しいわけではありませんので、間違いがあるかも知れません。また、この言語も足して欲しいという場合もあると思います。その場合は、追記・修正依頼で指摘して頂くと助かります。


不公平感が出ないように、私の考えの立場を言っておきます。私は「『狭義の参照渡し』と混合するから『広義の参照渡しは』使うべきではない」と考えています。ただ、この考えを全ての人に押しつける気はなく、C++等を学ぶことが生涯ない人は別にそれでいいのではないかと思っています。「広義の参照渡し」の事例は集めていますが、私自身「広義の参照渡し」なるものの使用を前述の理由で避けていたため、どのような場合に使われる事が多いことを知っていても、その定義がどのようなものか、どのような場合に使うべきかまでは考察したことがありません。そのため、既にそれらに確固たる信念をもって使用されている方にお聞きすべく、この質問をすることにしました。

この質問で、別に「広義の参照渡し」を使うなと言っているわけではありません。どのような意味で「広義の参照渡し」を使っているのかを知りたいという純粋なる知識欲から質問しています。

juner, LouiS0616👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/05/18 22:51

飽きないでちゅか?
raccy

2019/05/18 23:42

飽きない理由を追記しました。
退会済みユーザー

退会済みユーザー

2019/05/18 23:51

うーんと、この論争をちて、誰が得をするのかなぁ?って疑問なのでちゅ。 勉強熱心な事はすばらちいとおもうのでちゅが、 こんな論争をちても、社会の問題は何も解決ちないと思うのでちゅね。 ぎじゅつしゃの知的好奇心なのはわかるのでちゅが、 これが白黒ついたからといって何かあたらちい発想が生まれてくるとも、 到底思えないのでちゅよねぇ…。
xebme

2019/05/19 01:15

URLが広義の参照であるか?勝手にGCされるけど。遊びの範囲を拡げると面白くなる可能性はあります。
退会済みユーザー

退会済みユーザー

2019/05/19 01:28

>面白くなる可能性はあります。 だからあなた達は、「オタクキモーい」って言われるんだと思いまちゅ。
otn

2019/05/19 09:10 編集

「raccy 2019/05/19 09:16」 のコメントを見ましたが、私も質問を見てnskydivingさんと同じ誤解をしました。私が「"広義の参照渡し"」でググると5件でした。ネット上にほとんど無い表現を使わないようにしようという意見は無意味だなと思いました。 「ポインター(やリファレンス)の値渡しのことを、参照渡しと表現することを止めよう」 ということであれば、そう書いた方が良いです。 少なくとも、あなたの文脈なら、 > 「広義の参照渡し」 じゃなくて、 > 広義の「参照渡し」 と書いた方が良い。
Zuishin

2019/05/19 13:11 編集

「広義の参照渡し」というカッコの使い方については [C言語での値渡しと参照渡しの使い分けについて](https://teratail.com/questions/189570#reply-281419) のコメント欄における私の書いたものが出典のようです。 その更なる出典は HogeAnimalLover さんの発言でしたが、そこから先の出典については何度お尋ねしても、明確に示されませんでした。最後に漏らされた言葉によると、どうやら「宗教」ということのようです。
raccy

2019/05/19 14:02

「広義の参照渡し」と「狭義の参照渡し」と表現しているのは、そのまま"参照渡し"と書かれてしまうと、回答者がどちらの意味で言っているのかがわからなくなるため、わざわざ「」で強調、かつ、分離できないように「」内に含める形にしています。この質問において明確に区別するための表現ですので、一般的にそのような表現があると考えているわけではありません。もちろん、「区別できない」と言う考えもあり得ると想定しており、その場合は、その旨と理由を書いて欲しいとしています。
raccy

2019/05/19 14:23

なお、言葉選びで先のZuishinさんがはったURL先のコメントのやり取りを参考にしています。別に「参照渡しA」と「参照渡しB」としてもよかったのですが、そちらの方が、下手に混乱を招かずに良かったのでしょうかね。
otn

2019/05/19 15:02

「」は強調とは違うので、強調したいなら、マークダウンでBoldにした方が誤解がなかったでです。 コメント欄だとマークダウンが使えないので、**広義の参照渡し** とか。
raccy

2019/05/19 21:44

すいません、上の文で、「わざわざ『』で強調」のところの強調は、地の文との区別を強調したいという意味です。その言葉を強調したいという意味ではありません。字足らず過ぎて申し訳ないです。
guest

回答3

0

Pythonのように値渡しであると公式ドキュメントに書いてある言語において、「参照渡し」が意味する物が何であるのかと言うことです。

pythonでいうと、「オブジェクトの値そのもの」を変数として持つ方法がなく、かならず参照(インスタンスへのポインタというか)を持つ形になります。そのため、

引数は 値渡し (call by value) で関数に渡されることになります (ここでの 値 (value) とは常にオブジェクトへの 参照(reference) をいい、オブジェクトの値そのものではありません) [1]

注として、

[1] 実際には、オブジェクトへの参照渡し (call by object reference) と書けばよいのかもしれません。というのは、変更可能なオブジェクトが渡されると、関数の呼び出し側は、呼び出された側の関数がオブジェクトに行ったどんな変更 (例えばリストに挿入された要素) にも出くわすことになるからです。

となります。

なのでむしろ、「参照渡ししかない」という言い方をしているドキュメントを呼んだことがあった気がします。

「変更可能なオブジェクトが渡されると、関数の呼び出し側は、呼び出された側の関数がオブジェクトに行ったどんな変更 (例えばリストに挿入された要素) にも出くわす」という書き方は面白く、つまり、引数のオブジェクトに対する副作用が発生しうる渡し方と、値のコピーを受け取る(副作用が起きない)渡し方があるという捉え方があるといえます。

また、その定義から、C、Java、JavaScript、Python、Ruby、Groovy、Go、Haskell、Scala、Kotlin、R、Lua等の「狭義の参照渡し」が無い言語において「広義の参照渡し」とは具体的にどのような動作のことを指すのかの説明も加えていただければ幸いです。逆に「広義の参照渡し」すらない言語はどのような物があるのかも教えて頂くと助かります。

なので、「引数として渡したオブジェクトに対する副作用を起こしうる渡し方」を「広義の参照渡し」と自分なら呼ぶかもしれないです。

Pythonはすべて「広義の参照渡し」ですし、JavaScriptもプリミティブ型を除き同様の振る舞いです。

投稿2019/05/20 09:32

otolab

総合スコア765

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

raccy

2019/05/20 10:46

なるほど「副作用を起こしうる」が基準になると言うことですか。そうなると、Pythonの`int`や`str`等のイミュータブルなオブジェクトの場合は、「副作用を起こしうる」ことは無いので「広義の参照渡し」にはならないとなるといったところでしょうか?JavaScriptのプリミティブ型もイミュータブルですので、「広義の参照渡し」にはならないのと同じような感じにです。 しかし、この視点はなかったです。C++で`int f(const std::vector& v)`なんて書いた場合、「狭義の参照渡し」のひとつですが、`const`修飾子によって「副作用を起こしうる」ことは無いので「広義の参照渡し」にはならないとなるとなるのですね。「狭義の参照渡し」はすべて「広義の参照渡し」に入ると思って、狭義・広義の言葉を使いますが、失敗だったようです。もっと良い表現を誰か提案いてくれると助かります。「参照渡しA」や「参照渡しB」では味気ないですので。 そういえば、「オブジェクトへの参照渡し (call by object reference) 」ですが、「オブジェクトへの」と「参照渡し」は分離して考えらえると言うことでいいでしょうか?英語では不可分に見えますが。
otolab

2019/05/20 12:01

> なるほど「副作用を起こしうる」が基準になると言うことですか。そうなると、Pythonの`int`や`str`等のイミュータブルなオブジェクトの場合は、「副作用を起こしうる」ことは無いので「広義の参照渡し」にはならないとなるといったところでしょうか?JavaScriptのプリミティブ型もイミュータブルですので、「広義の参照渡し」にはならないのと同じような感じにです。 そういうイメージです。 > C++で`int f(const std::vector& v)`なんて書いた場合、「狭義の参照渡し」のひとつですが、`const`修飾子によって「副作用を起こしうる」ことは無いので「広義の参照渡し」にはならないとなるとなるのですね。 むむ、それは参照渡しですね...。適当言ってしまった。 ただ最終的に同じインスタンスにアクセスしている状態であれば(read / write何れにせよ)、それは参照渡しなのだと思います。 > そういえば、「オブジェクトへの参照渡し (call by object reference) 」ですが、「オブジェクトへの」と「参照渡し」は分離して考えらえると言うことでいいでしょうか?英語では不可分に見えますが。 pythonの場合、「プリミティブ型の値渡ししかない」かつ「プリミティブ型としてオブジェクトへの参照型がある(オブジェクトの実体は変数にならない)」という仕様だったはずです。 なので、 「プリミティブ型の値渡ししかない」「オブジェクトは参照渡しである」が両立する感じですね。 「参照型以外のプリミティブ型を例外として、全て参照渡し」という言い方もできるわけです。
guest

0

Swift の inout の場合は「参照渡し」の語は概念の説明に使うことが多く, 実際の呼称としては inout 渡しとか in-out 渡しという「見たまんま」の呼び方のほうが多い気がします.

自分自身は C++ や C# を扱った経験があるため, 広義の参照渡しのほうの意味で「参照渡し」という語を用いることはあまりありませんが, 自分が今まで見てきた広義の参照渡しの事例の共通項を探ると:

  • 「それ自身の値は意味を持たず, 何らかの値を参照するための値」を「渡す」.

という感じかなと思います.
前者は名前通りの「参照」という語のこともありますし, C言語などであれば「アドレス」が相当します.

ここからは推測になってしまいますが, 多くの「広義の参照渡し」事例のルーツとなっていると思われるのは現在主流の多くの言語の源流となった, C言語ではないでしょうか.

(C++ でない, 純粋な) C言語には狭義の参照渡しが存在しないため, 狭義の参照渡しで実現したいような処理はアドレスを渡して代替するほかありません.

すると「こういうこと (参照渡しが必要になりそうなこと) がしたい」 -> 「やりたいことはプログラミング一般で言えば参照渡しと呼ばれる概念を使えばいいが, C言語には直接それに相当する機能はないため, こう実装する」 -> 「参照渡しはC言語ではこう実装する」 -> 「C言語ではこれが参照渡し」みたいな誤解に繋がったのではないかと.

また, 純C言語は:

  • 大きなデータ構造を作ることはできるが, それを単に渡すと (最適化にも依るが) コピーが走ってしまう.
  • 戻り値はひとつだけ.
  • 例外など「戻り値以外で外部へエラーを戻す手段」がないため 「欲しい値」か「エラー情報」のどちらかをダブルポインタを使って得たい場面が多い. (それ以外だと, グローバル変数や別の関数からエラー情報を得るなんて実装が普通にありますが, 当然副作用など注意が必要)
  • 文字列などの非常によく使われるデータ構造をはじめ, 標準ライブラリの多くの関数もアドレスの存在を前提として設計されている.

などの理由で, あまり用語を知らない初心者でもアドレスを渡す場面が多いため誤解を促進しやすい環境と言えます.

そして知名度の高い言語で誤解のある状態で, 「参照」という概念のある言語が広まるのが追い討ちになります.
C言語で上記のまま覚えた人は, その言語で同じことを実現するために「参照」という値を「渡す」ことを「参照渡し」と呼び始めます.
するとC言語を知らない方は「参照」を「渡す」から「参照渡し」かあ, と一層誤解を広めてしまいます.

...という感じではないかなぁ, と推測します.

投稿2019/05/28 07:35

kagilinn

総合スコア354

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kagilinn

2019/05/28 07:42

「Swift の inout の場合は「参照渡し」の語は概念の説明に使うことが多く, 実際の呼称としては inout 渡しとか in-out 渡しという「見たまんま」の呼び方のほうが多い気がします」 について, ちょっと自分でも誤解があったかも知れません. ただ Swift でも「参照渡し」を「参照という値」を「渡す」意味で使っている事例があったりするので, 「Swift で参照渡しは inout」と表現してもやはり誤解される恐れがあるということは補足しておきます.
raccy

2019/05/28 09:48

結局の所「広義の参照渡し」は誤解であるという所なのでしょうか?C++等を知れば、いつかは誤解が解けて、言わなくなるはずと言ったところでしょうか…。 うーん、これまで多くの「広義の参照渡し」を使っている人を見てきましたが、C++の「狭義の参照渡し」をいくら説明しても、彼らは「広義の参照渡し」を使い続けていましたので、誤解等から来ていない、何かもっと信念みたいな事があるに違いないと期待しているんですがね。
kagilinn

2019/05/28 10:06 編集

だとすれば「広義の参照渡し」とは, 「渡し方そのもの」「渡す手段」ではなく, 「考え方」というか, 「そうする目的」というか, そういう何かを指すのだと思います. レイヤが違っているというか. つまり, どんな手段を使ったとしても: * 呼ばれた側に, 呼び出し側が持っているデータを変更したり間接参照をさせるという考え方 * 呼ばれた側から, 呼び出し側が持っているデータを変更または間接参照したい, という目的 で引数を使うのであれば, それは「広義の参照渡し」なのではないでしょうか.
kagilinn

2019/05/28 10:16 編集

例えば, 古い処理系で「データを変更させるには, グローバル変数として置いた配列を使うしかない」とすれば, サブルーチン側で配列を参照・変更できるようインデックスを渡すのも「広義の参照渡し」なのでは.
guest

0

広義の参照渡し」で Google 検索しましたが、10 件しかヒットしませんでした。

「広義の参照渡し」は一般的な用語ではなく、その文脈の中だけで使われた言葉だと思われます。

ですので、

「広義の参照渡し」とは何か?

という問いに対しては、その言葉を使った人に聞いてみないと分からないと思います。

おそらくですが、
「引数の値を間接的に読み取りおよび書き込みが可能な機能」
または
「狭義の参照渡しを代替えする機能」
みたいな意味合いで使っているのではないかと思います。

投稿2019/05/19 00:00

nskydiving

総合スコア6500

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/05/19 00:14

> Google 検索しましたが、10 件しかヒットしませんでした。 ひさちぶりに、この無意味な論拠を見まちた。 頭おかちいでちゅね。
raccy

2019/05/19 00:16

質問文がちょっと悪かったようですので、ちょっと修正しています。この質問で言っている「広義の参照渡し」というのは"広義の参照渡し"と表現される事柄のことではありません。最初に述べた機能としての「参照渡し」以外に対して「参照渡し」と使っている、曰く、広義の意味での「参照渡し」のことを、機能としての「参照渡し」と区別するために「広義の参照渡し」としています。わかりにくくて申し訳ありません。 nskydivingさんも使ったことがないのですよね?そうなるとどうしても推測の域をでないですよね。渡しもなんとなくそんなかんじじゃないかなというのはわかりますが、なんとなくじゃない回答が欲しいところです。
nskydiving

2019/05/19 01:26

私自身は「広義の参照渡し」という言葉は使ったことありません。 しかし、「広義の〇〇」という日本語表現には「厳密な意味ではなく」という意味合いがあると思うので「なんとなくじゃない回答が欲しい」というのはちょっと難しい気がしますね。
cateye

2019/05/19 01:58

#アセンブラで言えばレジスタ(orスタック)に乗ってるのが、データなのかアドレスなのかの違いだけなんだけどなぁ・・・
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問