(Go: >> BACK << -|- >> HOME <<)

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

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

言語別の意味や構文

編集

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

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

int f(void);

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

void g(void);

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

return文の形式は

return ;

または

return ;

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

return文の式が関数の戻り値の型と異なる場合、その値は、関数の戻り値の型を持つオブジェクトへの代入と同じ規則で暗黙的に型変換される[3][2]

return文に遭遇しないまま関数の終わりまでプログラムが実行された場合、そこに式を省略した return; が行われたと見なされる。ただし、C99とC++98では、main関数に限り、そのmain関数の戻り値の型が int であれば return 0; があったと見なされる(X3010 9頁 5.1.2.2.3、X3014 35頁 3.6.1 5節参照)。

戻り値の型が void である関数で式を指定することは、Cだと意味解析でできないとされているが、現在[いつ?]のC++では、結果がvoid型になる式であれば良いとされている(X3014 79頁 6.6.3 3節参照)。このためテンプレートでより汎用性を持たせることが可能になっている。

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

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

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

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

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

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

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

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

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

  • 構文1
return ;
  • 構文2
return ;

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

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

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

  • 構文1
return
 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
return 行番号
 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文

編集

ラムダ式をサポートするほとんどの言語では、形式のラムダ[5]を許可する(C++を除く[6])。式形式のラムダでは、値を返すためのreturn文の記述が不要となる。以下はC#の例である。

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

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

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

Pascal

編集

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

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手続きの拡張版を用いることで、結果の設定と脱出を同時に行なったりすることもできる[7]。引数を受け取るExit手続きは、Cのreturn文と類似の動作となる。

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;

脚注

編集
  1. ^ ISO/IEC 9899:1999, §6.8.6.4 The return statement, ¶1
  2. ^ a b ISO/IEC 14882:1998, §6.6.3 The return statement, ¶2
  3. ^ ISO/IEC 9899:1999, §6.8.6.4 The return statement, ¶3
  4. ^ Chapter 14. Blocks and Statements
  5. ^ ラムダ式 - ラムダ式と匿名関数 - C# reference | Microsoft Learn
  6. ^ ラムダ式 [N2927] - cpprefjp C++日本語リファレンス
  7. ^ Function results | Free Pascal

参考文献

編集

以下の3つは、C/C++の節でのみ参照した。