Ada 2020 (53日目) - 10月21日の電子会議の結果

10月25日に行われた電子会議の議事録が公開されました。

Put_ImageとAda.Strings.Text_Buffersの修正

'Put_Image 属性('Image 属性)を Unchecked_Union に使った場合の挙動が Program_Error から実装依存の文字列を返すように修正されました。 Unchecked_Union はどのケースで解釈していいのか定まりませんので、例えば "(UNCHECKED UNION)" のような文字列を返すことが提案されています。 例外にされますとデバッグ出力も気楽にできませんし歓迎です。

Ada.Strings.Text_Buffers はネストされたインデント/アンインデントに対応しました。

ほとんどの宣言にアスペクトが付けられるように

なりました。

discriminantでしたり拡張return文の返値用オブジェクトでしたり。 隅から隅まで。

むしろどの宣言がアスペクトを付けられないままにされているのかを見ていったほうがわかりやすいと思います。

アスペクトが付けられない宣言

  • incomplete型。

  • generic の引数としてのincomplete型。

  • 列挙型の要素。 type T is (A, B with Inline, Pack, C); みたいに書いたときに Pack がアスペクトなのか要素なのか曖昧になります。

  • parallel for文のチャンク。

  • for文その他のインデックスやprocedural iteratorのパラメータ等。

  • 例外ハンドラで受け取るパラメータ。 (... exception when E : others => ...E のことです。)

列挙型の要素は文法が曖昧になるのが理由であり用途が考えられるだけに残念です。 (内部表現や 'Image の結果を指定する等)

後は妥当でしょう。

Preelaborable_Initializationアスペクト

pragma Preelaborable_Initialization がアスペクトとしても書けるようになりました。

これまでアスペクト化が阻まれていた理由としましてはアスペクトは可視性によって変化しないと決められていたからだそうです。

Preelaborable_Initialization の性質は可視性の影響を受けます。

package Pkg1 with Preelaborate is
   type T is private;
private
   type T is new Integer;
end Pkg1;

package Pkg1.Child with Preelaborate is
   A : T; -- error
private
   B : T; -- ok
end Pkg1.Child;

抽象型 Pkg1.T は中身が見えない箇所からは実行時の初期化が必要かどうかは不明として扱われ、中身が見える箇所からは実行時の初期化は不要とわかります。

pragma Preelaborable_Initialization は中身が見えなくても実行時の初期化が不要ですよとコンパイラに伝えます。

package Pkg1 with Preelaborate is
   type T is private;
   pragma Preelaborable_Initialization (T);
...

これで A の宣言もコンパイルできるようになります。

このpragmaを付けていない場合が問題で、可視性によって Preelaborable_Initialization かどうかが切り替わっています。 アスペクトにしてしまいますと同じ型なのに可視性で False から True に切り替わる謎アスペクトになってしまいます。

これまではこのようなアスペクトは認められていませんでしたが、例外的にOKということにして Preelaborable_Initialization がアスペクトとしても書けるようになりました。

package Pkg1 with Preelaborate is
   type T is private
      with Preelaborable_Initialization => True;
...

うーむ?

Append_One廃止とAppendのオーバーロードの分割

VectorsDoubly_Linked_Lists に追加される予定でした Append_One が廃止されます。 やっぱり不格好と思われていたようで……。

代わりに Append が要素型を取る版とコンテナ自体の型を取る版でオーバーロードされていたのが分割されて後者が Append_Vector になります。

そもそもの問題はコンテナがユーザー定義aggregate式で書けるようになったせいで Append (Container, (1, 2)); みたいな呼び出しで (1, 2) が要素型としてもコンテナ自体としても解釈可能な場合が出てしまったことでした。 曖昧さのない Append_One を追加するか Append 自体から曖昧さを取り除くかの二択です。

ここまで互換性重視で前者の流れで来ていましたがこの土壇場に来てひっくり返りました。

Ada2005、2012とは非互換になり Vectors.Append でコンテナ自体を追加していたコードは Append_Vector に書き換える必要があります。 (Doubly_Linked_Lists.Append の方は元からオーバーロードはされていませんでした。 単に Append_One の追加が取り消されるだけです。)

……過去記事の修正点多い……めんどくさい……。

6日目10日目35日目非互換性52日目を修正しました。

Ada.Strings.BoundedAda.Strings.Unbounded にも同様にオーバーロードされた Append はあるわけで、もし String_LiteralAggregate アスペクトが追加されるようなことがあれば同様の修正が必要になると思われます。

Qualified式のrenames

任意の値が renames できるようになってしまったことに関して早速問題点が見つかってます。

declare
   X : Integer := 1;
   Y : Positive renames Positive'(X);
begin
   X := -1;

型を範囲を指定した subtype に変えながら renames した後で元の変数を書き換えたらどうなるのでしょうか?

というわけで変数の型を変えながらの renames はコンパイルエラーになりました。 エラーになるのは変数のみで定数や一時オブジェクト(式や関数の結果)でしたらOKです。

declare
   X : Integer := 1;
   Y : Positive renames Positive'(+X); -- 単項 "+" の返す一時オブジェクト
begin
   X := -1; -- Yは1のまま

その他文面等の修正

例によって文面等の修正がまとめてひとつのAIで行われています。

関連AI

  • AI12-0384-2 Fixups for Put_Image and Text_Buffers

  • AI12-0398-1 Most declarations should allow aspect specifications

  • AI12-0399-1 Aspect specification for Preelaborable_Initialization

  • AI12-0400-1 Ambiguities associated with Vector Append and container aggregates

  • AI12-0401-1 Renaming of a qualified expression of a variable

  • AI12-0403-1 Presentation issues from Draft 26 review