limited型のreturn

gccにはまだ実装されて無いのですが、ついでに書いておきますか。匿名アクセス型のnot nullどころではない互換性無視仕様変更。
AdaはPascalやらEiffelやらと異なり、return文を使う言語です。私はResult変数のほうが好きなのですが、Result変数には、呼び出し側が確保した空間への参照で実現できるので、巨大な値を返すときもコピーが発生しないというメリットと同時に、オブジェクトを値として返すときコンストラクタ呼び出しの書きようが無いという割とどうしようもない構文上のデメリットもあります。(EiffelにしろDelphiにしろオブジェクトは参照ですし、Delphi以前のObjectPascalにしてもコンストラクタはNewとDisposeのついでに呼べるだけで事実上単なるメソッドでした。)
AdaはC++同様にオブジェクトが値埋め込みですので、return文がマッチするわけですね。AdaにはC++のようなコンストラクタはありませんが、代わりにdiscriminantsがありますので。
ですのでAdaは、return文は、C++同様の「値を構築してそれを返す」モデルでした。Ada95までは。
これがAda2005では、「呼び出し側の文脈で値を構築する」build-in-placeモデルに変更されています。何が違うんだって話ですが、関数呼出しがaggregateと同じ扱いになってます。つまりnew T'(Func(...))などと書いても、呼び出し側の文脈がnewということで、return上の式は新たに確保されたメモリの上で実行されます。C++でnew T(Func(...))と書けばreturn上のコンストラクタとその後new T(...)でコピーコンストラクタと、値の構築が2回実行されるところが、Ada2005ではreturn文の1回だけとなります。
何が嬉しいかといいますと、limited型、つまり代入演算ができない型を、関数の返値としても、呼び出し側はそれを引き続きnewなり変数の初期値にするなりaggregateの一部にするなりまたreturnに渡すなりしていろいろ使える、Ada2005にはこれもgccには未実装のextended returnで、returnで返す値の作成後もさらに同関数上に居残って処理を続けることができますので、関数の中から外へ、同一のオブジェクトをバトンタッチできるようになるわけです。少し考えればわかりますが、これはC++のコンストラクタの完全なスーパーセットです。その辺の関数が全部コンストラクタ扱いになるわけです。
…で、何が非互換なのかと言いますと、C++やAda95の「値を構築してそれを返す」モデルでは、代入演算のできない型を関数の返値とするのは事実上無意味だったわけです。まあ呼び出し側はその結果を使って一回だけメソッドが呼べることは呼べますし、ほっといてもデストラクタは呼ばれるのでRAIIにも使えますが。
…で、Ada95は、これを有効活用すべく、limited型を返す関数は、全て、C++で言うところの&を付けた参照返しである、という、いやそれはそれでどうよ…?な規定がなされてました。つまり既存の変数をreturnに渡しても、やっぱりコピーは起きなかったわけです。
しかしこれがAda2005のbuild-in-placeに変更されたことで、新しくnewで確保するメモリをlimited型の返値で初期化するといったことが可能となりました。ということは、既存の変数を返す場合はコピーが必要になってしまいます。
…で、あっさり、limited型のreturnは参照返しであるという規定は消滅しました。
…ということはつまり、既存のlimited型変数をreturnに渡してた箇所は全滅となるわけです。
…ということはつまり、Ada95のlimited型を返す関数を、Ada2005からは呼び出せないわけです。
gccのこの辺の実装が全く進んでない理由が想像できちゃいますね…。どう互換を取るか悩んでるに違いない。