Ada 2020 (52日目) - 9月9日の電子会議の結果

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

parallel for文にアスペクト指定

parallel for文にアスペクトを指定できるようになります。

declare
   Data : array (1 .. 1280) of Float;
   Total : Float := 0.0;
begin
   parallel (Chunk in 1 .. 2) with Gang -- implementation-defined
   for I in 0 .. 9 loop
      parallel with Vector => 128 -- implementation-defined
      for J in 1 .. 128 loop
         Total := Total + Data (I * 128 + J);
      end loop;
   end loop;

具体的なアスペクトは定義されておらず、実装依存のオプションを渡すことができます。

余談ですが、gcc 9からOpenACC 2.5がサポートされました。 Adaフロントエンドでもgcc 9で関連pragma群が一度は追加されましたもののgcc 11では廃止されてしまいました。 今後もしparallel for文の実装にOpenMPやOpenACCが選べるということになればオプションを渡すためにこの構文が使える……のかもしれません。

これに関係してユーザー定義アスペクトも議論されましたが採択されませんでした。

仮引数にアスペクト指定

もできるようになります。

access型とoutパラメータでの変換

ここまで Default_Value を持つ基本型とoutパラメータ周りが細々修正されてきました。 今度はaccess型に対する似たような修正です。

outパラメータの実引数の中で共通の祖先を持たないaccess型の変換を行った場合、実装は元の値ではなく null を渡しても構わなくなります。 (サブプログラムに渡す時の話です。 書き戻しには影響ありませんのでサブプログラムの中で代入した値が捨てられるようなことはありません。)

declare
   type A1 is access all Integer;
   procedure Nop (X : out A1) is
   begin
      null;
   end Nop;
   V : aliased Integer;
   type A2 is access all Integer;
   D2 : A2 := V'Access;
   type A3 is new A1;
   D3 : A3 := V'Access;
begin
   Nop (A1 (D2)); -- D2 = null or V'Access
   Nop (A1 (D3)); -- D3 = V'Access

この例では D2 の型は A1 と無関係に定義されていますので null になるかもしれません。 D3 の型は A1 から派生していますので値はそのままになります。

現状GNATのみこの挙動です。 生存期間の異なるaccess型同士の変換では適切なAccessibility_Checkを行う必要があり、そのコストを嫌ったのか単にさぼっているのか。 他のコンパイラは他のコンパイラでそれぞれ細かい非互換を抱えていて、結果大した問題ではないと追認されたようです……。

ちなみにこのケースに限らずoutパラメータの場合は not null が付いていても一時的に null になることはあります。 実際に使用されたり実引数に書き戻される時にはチェックされます。

outパラメータにはサブプログラムの中できちんと代入しましょう。

いっそaccess型のoutパラメータは全部 null で初期化されることにすれば元の値を渡す必要がなくなって効率的になりますが、影響が大きすぎるためそこまで踏み込まれませんでした。

未知のアスペクト

実装はpragma同様に未知のアスペクトを無視してもよいことになります。

それに伴ってpragma RestrictionsNo_Unrecognized_AspectsNo_Unrecognized_Pragmas が追加されます。

pragma Restrictions (No_Unrecognized_Aspects)

未知のアスペクトを無視せずコンパイルエラーにします。

pragma Restrictions (No_Unrecognized_Pragmas)

未知のpragmaを無視せずコンパイルエラーにします。

サブプログラムを指す匿名のaccess型の返値

規格の文面を厳密に解釈しますとサブプログラムを指す匿名のaccess型の返値は呼び出した箇所と同じレベルになる……ようです。

すると実際には問題なくてもネストされた先で呼び出された結果をより浅いレベルで宣言された変数に代入できない……そうです。

サブプログラムを指す匿名のaccess型もオブジェクトを指す匿名のaccess型と同じルールに従うよう修正される……らしいです。

(理解が怪しいことがわかる文章。)

Ada.Containers.Doubly_Linked_Lists.Append_One

Append_OneVectors だけではなく Doubly_Linked_Lists にも追加されます。 35日目に追記しました。

変換の式中でのraise式

raise式がAccessibility_Check等の各種チェックに引っかからないことが明記されます。

制約に違反した定数

こういうやつのことです。

Bad : constant Positive := -1;

もちろん警告も出ますし実行時には Constraint_Error になるわけですが、Ada 2020ではstatic関数が追加されてコンパイル時に色々できるようになりました。 そのため制約に違反した定数はstatic扱いされないことが明記されます。

名前付き定数とユーザー定義リテラル

型無しのnamed numberがユーザー定義リテラルを持つ型に使えるようになります。

declare
   U1 : constant := 100 / 2;
   X1 : Ada.Numerics.Big_Numbers.Big_Integers.Big_Integer := U1;
   U2 : constant := 123.45 / 2.0;
   X2 : Ada.Numerics.Big_Numbers.Big_Reals.Big_Real := U2;

変換関数には10進数表記された文字列が渡されます。

また Real_Literal アスペクトに指定する変換関数はオーバーロードしてふたつの引数を取ることもできるようになります。 その場合は分数として第1引数に分子、第2引数に分母が10進数の整数表記で渡されるようになりますので誤差の心配もなくなりました。

(あれ? 実装は実数定数を浮動小数点形式で持つわけにはいかなくなったのでは?)

Default_Initial_Conditionの継承

Default_Initial_Condition アスペクトは継承されることになっていましたが、具体的にどういう処理がなされるかは明記されていませんでした。

Post'Class 同様と明記されました。

その他文面等の修正

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

またアスペクト周りの文面もひとつのAI(AI12-0396-1)で細々修正されています。

その他特記事項

Ada.Strings.Text_Buffers

がネストされたインデント/アンインデントに対応するかもしれません。

結果を複数行で返す 'Image 属性が書きやすくなります。

暗黙のインスタンス化

自体が見送られることになりました。

関連AI

  • AI12-0355-2 Aspect specifications for parallel constructs

  • AI12-0378-1 View conversions and out parameters of access types revisited

  • AI12-0388-1 Still More Presentation issues

  • AI12-0389-1 Ignoring unrecognized aspects

  • AI12-0390-1 Conversions of anonymous access function results

  • AI12-0391-1 List containers need Append_One

  • AI12-0392-1 Conditional expressions containing raise expressions

  • AI12-0393-1 No invalid static constants

  • AI12-0394-1 Named Numbers and User-Defined Numeric Literals

  • AI12-0395-1 Allow aspect_specifications on formal parameters

  • AI12-0396-1 Fixups for various aspects of aspects

  • AI12-0397-1 Default_Initial_Condition applied to derived type