Return文

**return文**（リターンぶん、）とは、プログラミング言語における文の一つである。goto文やbreak文、continue文のようなジャンプ文 () に分類される。サブルーチンからの復帰に使われ、復帰と同時に値を返すことができる。その値は**戻り値**（もどりち、）、**返り値**（かえりち）、**返却値**（へんきゃくち）あるいはそのまま**return値**（リターンち）などと呼ばれる。

日本産業規格（旧称・日本工業規格）では、C言語の国際標準規格「ISO/IEC 9899:1999」（通称C99）の翻訳「JIS X 3010:2003」およびC++の国際標準規格「ISO/IEC 14882:2003」（通称C++03）の翻訳「JIS X 3014:2003」において、「返却値」という訳語を使用している。

言語によっては、return文ではなくreturn式となっているものもある。

## 言語別の意味や構文
### C/C++
CおよびC++において、return文とは、関数を実行した結果や、その処理が成功したかどうかなどを示すデータを呼び出し元に渡すとともに、関数を終了させ呼び出し側に制御を戻す働きを持つ文である。return文によって関数の呼び出し元にデータを渡すことを、**値を返す**と言う。

return文によって返される値の型は、関数の定義時やプロトタイプ宣言時に指定する。例えば、

```c
int f(void);
```

という宣言は、関数 `f()` が `int` 型の値を返すことを表す。

```c
void g(void);
```

という宣言は、関数 `g()` が値を返さないことを表す。このvoidは形式的な型であり、メモリ上のオブジェクトとして実体化することはできない。

return文の形式は

```c
return 式;
```

または

```c
return ;
```

のいずれかでなければならない。return文に式が伴う場合、その式の評価結果がreturn文の戻り値となる。C/C++において、構文上はreturn文を省略可能であるが、意味解析の段階において、C99では、式を持つ文は戻り値の型がである関数内で出現してはならず、式を持たない文は戻り値の型がである関数内でのみ出現してよいことになっている。C++では、関数の終わりに到達して脱出することは値なしの文がある場合と同等であり、値を返すべき関数でこれが発生すると未定義動作を引き起こす。そのため、この規則に違反するコードに対して、コンパイラは通例警告を発する。

return文の式が関数の戻り値の型と異なる場合、その値は、関数の戻り値の型を持つオブジェクトへの代入と同じ規則で暗黙的に型変換される。C++の場合、return文は一時オブジェクトの構築とコピーを伴うことがある。

return文に遭遇しないまま関数の終わりまでプログラムが実行された場合、そこに式を省略したが記述されたものとみなされる。ただし、C99とC++98では、main関数に限り、その`main`関数の戻り値の型がであれば、が記述されたものとみなされる。

戻り値の型がである関数で式を持つreturn文が現れることは、前述の通りCでは許されていないが、C++98では型の式を持つ場合に限り許されている。このためテンプレートでより汎用性を持たせることが可能になっている。

```c++
template<typename T> T 
func_call(T fn)
{
    return fn();
}
```

もし、テンプレート引数 `T` にint型を返す関数を与えてこの関数テンプレートfunc_callを実体化させると、概念的には次のようになる。

```c++
//擬似コード
int func_call(int fn())
{
    return fn();
}
```

そして、戻り値の型が `void` の関数を与えると、やはり概念的には次のようになる。

```c++
//擬似コード
void func_call(void fn())
{
    return fn();
}
```

ここで `fn()` の型は `void` になるが、`func_call` の戻り値の型も `void` であるため、もとの関数テンプレート `func_call` に戻り値の型が `void` の関数を与えてもコンパイル可能である。仮にこれが認められず、Cのように戻り値の型も `void` の関数内では、式を省略したreturn文しか許されないとすると、もとの `func_call` に対して次のような特殊化を用意しなければならない。

```c++
template<>
void func_call(void (*fn)())
{
    fn();
}
```

一部の古いC++コンパイラでは、void型の式をreturnに書けず、実際にこのような対策を取る必要があった。なお、この特殊化では、関数オブジェクトを対象にしていない。

#### noreturn属性
関数内から例外をスローする、あるいは`std::exit()`関数や`std::abort()`関数を呼び出してプログラムを終了するなどの理由で、を決して実行しない関数が定義される場合がある。このような特殊な仕様の関数を他の関数から呼び出す場合、呼び出し後の処理は決して実行されないことになるが、もし呼び出し元の関数の戻り値がでない場合、前述のように戻り値の型に準じた式を伴う文が存在しなければ、コンパイラが警告を発する対象となってしまう。

C++11では、を決して実行しない関数であることを示すことができる属性の構文が追加された。

C11では類似機能として関数指定子が追加されたが、C23ではC++同様の属性の構文が追加されるため、は非推奨となる予定である。

### Java
Javaにおいて、return文とは、実行しているメソッドから抜け出すための文である。値を返してメソッドから抜け出す場合には、そのメソッドに適切な戻り値を設定しなければならない。C言語などと同様に、以下の2通りの構文が認められている。

* 構文1
:
```java
return ;
```

* 構文2
:
```java
return 式;
```


`void`を使って宣言されたメソッドや、コンストラクタ、ラムダ式など、メソッドの戻り値が無い（値を返さない）場合は構文1を用い、返す場合は構文2を用いる。構文1は省略可能であり、処理がメソッド末尾に到達した場合、暗黙的に呼び出し元へ制御が戻る。

### BASIC
BASIC、あるいはVisual Basicのバージョン6までにおいて、return文とは、`gosub`によって飛んだサブルーチンから、元のメインルーチンへと戻る命令である。gosub元の行番号、もしくは構文の位置を記憶しておき、`return`と書かれた個所までプログラムの進行が辿り着くと、記憶していた次の命令もしくは行番号を読み、実行を続けていく。

BASICにおけるreturn文には、行番号を伴うものと伴わないものの2つがある。

* 構文1
:
```basic
return
```


:例
:
```basic
10 a=1:gosub 100
 20 a=2:gosub 100
 30 a=3:gosub 100
 40 a=4:gosub 100
 50 end
100 'サブルーチン
110 print a
120 return
```


上のプログラムリストの場合、行番号100から120がサブルーチンになり、行番号10～40はそれぞれサブルーチンへと飛び、行番号120から再びメインルーチンへと帰還する流れをとる。

また、BASICによってはreturn文に行番号を添えることで、メインルーチンへの帰還を行わずにプログラムを走らせることが可能なものもある。

* 構文2
:
```basic
return 行番号
```


:例
:
```basic
10 a=1:gosub 100
 20 a=2:gosub 100
 30 a=3:gosub 100
 40 a=4:gosub 100
 50 end
100 'サブルーチン
110 print a
120 if a<3 then return
130 if a>=3 then return 150
150 'サブルーチンからの離脱
160 print "end"
170 end
```


上の例では `a` の値として `3` が代入された行番号30からのサブルーチンへのジャンプ以降は、行番号130の `return 150` によってルーチンから解放され、行番号150へと飛ぶ。既にreturnを経ているため、仮にこの後にreturn文があっても行番号40に戻ることは二度と無く、エラーを返すこととなる。

また、多くのBASICではgosub returnはネストを作ることが可能であり、サブルーチンから更に別のサブルーチンへと飛ばせる。この場合、returnも二重に扱えることとなる。

ほとんどのBASICでは自らのルーチンへと飛ぶことも可能であるため、サブルーチンのネストはバグを生む原因にもなりえる。

## 関数型言語とreturn
関数型プログラミング言語では、関数内で最後に評価される式が戻り値となる。また、`if`-`else`のような制御構造は、文ではなく式であり、値を返す。そのため、手続き型言語における`return 式`といった構文を使う必要はない。ただしHaskellの`return`関数や、F#のコンピュテーション式におけるキーワードのように、別の目的でreturnという概念が使われることはある。


```fsharp
// F#
let f x =
    if x > 0.0 then
        2.0 * x
    else
        0.0
```


Rustのように、式（末尾にセミコロン`;`を伴うことでreturn文となる）をサポートするものの、省略して関数型言語のように書くことのできる言語も存在する。

```rust
fn f(x: f64) -> f64 {
    if x > 0.0 {
        2.0 * x
    }
    else {
        0.0
    }
}
```


Swift 5.1以降は、単一の式からなる関数においてを省略した書き方をサポートする。

```swift
func f(_ x: Double) -> Double {
    x > 0.0 ? 2.0 * x : 0.0
}
```

Swift 5.9以降はif文のほかにif式もサポートするようになったため、以下の書き方もできるようになっている。

```swift
func f(_ x: Double) -> Double {
    if x > 0.0 {
        2.0 * x
    }
    else {
        0.0
    }
}
```


## ラムダ式とreturn文
関数型言語およびラムダ式をサポートするほとんどの手続き型言語では、式形式のラムダを許可する（C++を除く）。式形式のラムダでは、値を返すための`return`文の記述が不要となる。以下はC#の例である。


```csharp
System.Func<double, double> f = (x) => x * x;
```


以下のように文形式のラムダを使って書くこともできるが、単純な演算であれば式形式のほうが簡潔になる。


```csharp
System.Func<double, double> f = (x) => { return x * x; };
```


C++のラムダ式では、値を返す場合は文を省略できない。

```cpp
auto f = [](double x) -> double { return x * x; };
```

ラムダ式の戻り値の型指定は省略することもでき、ラムダ式の中に文が1つもない場合はとみなされる。ラムダ式の中に文がある場合、その文の式から戻り値の型が推論されるが、複数の文があり、かつ戻り値の型が一意に定まらない場合は不適格（コンパイルエラー）となる。


```cpp
auto f = [](double x) {
    if (x > 0.0) {
        return 2.0 * x;
    }
    else {
        // 0 は int 型のリテラルであり、他の return 文と型が一致しない。
        // ラムダ式の戻り値の型を省略するとコンパイルエラーとなる。
        return 0;
    }
};
```


## Pascal
ISO標準Pascalにはreturn文に直接相当する構文はなく、最も簡潔な代替策はgoto文によるものである。関数の場合、関数と同じ名前の識別子を持つ定義済み変数に結果を代入することで戻り値を設定する。


```pascal
function FindFirstNegativeElementIndex(a: array of Integer): Integer;
label
  100;
var
  i: Integer;
begin
  for i := Low(a) to High(a) do begin
    if a[i] < 0 then begin
      FindFirstNegativeElementIndex := i;
      goto 100
    end
  end;
  FindFirstNegativeElementIndex := -1;
100:
  ;
end;
```


一部の処理系では、特殊変数`Result`を結果の設定に使用したり、`Exit`手続きを用いて手続きまたは関数の途中で脱出したり、引数を受け取る`Exit`手続きの拡張版を用いることで、結果の設定と脱出を同時に行なったりすることもできる。引数を受け取る`Exit`手続きは、Cのreturn文と類似の動作となる。


```pascal
function FindFirstNegativeElementIndex(a: array of Integer): Integer;
var
  i: Integer;
begin
  for i := Low(a) to High(a) do begin
    if a[i] < 0 then begin
      Exit(i)
    end
  end;
  Exit(-1)
end;
```


## COBOL
COBOLでは、RETURN文はSORT文に関連して、SORTファイルからSORTの後処理（OUTPUT PROCEDURE）へとレコードを返す働きを持つ文となっている。RETURN文は後処理内でREAD文の代わりにSORTファイルからレコードを読む働きを持つ。

## 脚注
### 注釈

### 出典

## 参考文献
以下の3つは、C/C++の節でのみ参照した。
* 『JIS X 3010:2003 プログラム言語C』 105頁（6.8.6.4 return文）ほか。
* 『JIS X 3014:2003 プログラム言語C++』 79頁（6.6.3 return文）ほか。
* 平林雅英　『ANSI C言語辞典』技術評論社、1989年（初版）、189頁（return文）。