Ada 202x (54日目) - 12月9日の電子会議の結果 =========================================== .. post:: Dec 19, 2020 :tags: ada, ada_2022 .. role:: strike `12月9日に行われた電子会議の議事録 `_\ が公開されました。 次回の会議は1月20日になるそうです。 案の定2020年内にまとまりませんでしたね……:strike:`先例からして呼称はAda 2021にはならずAda 2020のままになると思われます。` 結局Ada 2022になりました。 aliased引数を持つ関数呼び出し ----------------------------- 関数呼び出しではaliased引数に渡す実引数は呼び出し箇所よりも浅いレベルのものでなければなりませんでした。 .. code-block:: ada type T1 is record E1 : aliased Integer; end record; function F1 (A1 : aliased T1) return not null access Integer is begin return A1.E'Access; end F1; Global : aliased T1; function Caller1 return not null access Integer is begin return F1 (Global); end Caller1; function Caller2 (Argument : aliased T1) return not null access Integer is begin return F1 (Argument); end Caller1; function Caller3 (A1 : aliased T1) return not null access Integer is Local : aliased T1; begin return F1 (Local); -- error end Caller1; この例では ``Caller3`` はローカル変数の要素への参照を返そうとしていますのでエラーです。 このチェックは返値がaccess型を含まなくても、引数に ``aliased`` が付いているかどうかだけが条件でした。 .. code-block:: ada function F2 (A1 : aliased T1) return Integer is begin return A1.E; end F1; function Caller4 (A1 : aliased T1) return Integer is Local : aliased T1; begin return F1 (Local); -- error end Caller1; このような関数呼び出しが、返値の型が(匿名のaccess型を除く)基本型の場合は許されるようになります。 Stable_Propertiesの修正 ----------------------- 細かい点が詰められています。 - out引数には影響しないことが明記されました。 - access引数には影響しないことが明記されました。 - 使用される ``"="`` 演算子は ``in`` 式で用いられるものと同じものとされました。 可視性の上で別に定義した ``"="`` 演算子が見えていても使われません。 (``"and"`` 演算子についても同じ議論がなされたようですがこちらは明記されませんでした。) - 派生型で指定された ``Stable_Properties`` が継承されて ``overriding`` されていないプリミティブにも影響する、とされました。 - ``pragma Assertion_Policy (Post, ...);`` が ``Stable_Properties`` にも影響することが明記されました。 ``Post'Class`` も同様です。 - 事後条件の中で ``Stable_Properties`` で指定された関数が使われてさえすれば ``Stable_Properties`` による事後条件は生成されないことになっています。 この際引数については特に問われておらず関係の無さそうな呼び出しでも事後条件が生成されません。 この動作がこれで良いことが確認されました。 - in引数には影響するようです。 ただし ``Stable_Properties`` に指定された関数、``null`` 手続き、既定義の演算子、列挙型の要素名、``Global => null`` が付けられたものには影響しません。 (副作用が無ければチェックも不要ということでしょうか。 in引数を実は変更するサブプログラムもデフォルトの ``Global => all`` のままか、でなければ ``Global => overriding in out ...`` が明記されているかのはずですのでカバーされます。) - ``renames`` されたプリミティブにも影響するようです。 継承で使い辛そうなのは見直されてないです。 (くどい) package引数のAccessibility_Checkの修正 -------------------------------------- genericのpackage引数に対して静的なAccessibility_Checkが行われないようになります。 実行時のAccessibility_Checkは引き続き行われます。 package引数に関してはgeneric側だけ見てレキシカルに浅い深いを判定しても不要なエラーになるだけ……っぽいです。 勿論ここで言う静的なチェックとはtemplate型とコード共有型両方に適用できる静的なチェックのことで、template型のコンパイラであれば展開の過程で実行時のAccessibility_Checkを前倒しして警告できるはずです。 Preelaborable_Initialization属性 -------------------------------- 実はBounded版コンテナは規格上実装できなかったことが発覚してしまいました。 Bounded版コンテナにはpragma ``Preelaborable_Initialization`` が付けられています。 グローバル変数として宣言した場合に実行時の初期化を必要としてはいけません。 Bounded版コンテナは追加のアロケーションを行わずに仮引数 ``Element_Type`` を持つコンテナです。 ``Element_Type`` の領域はコンテナの中に持たないといけませんが、どうやっても ``Element_Type`` の初期化が必要となります。 (Tucker先生が挑戦されている様子をAIの中で読むことができます。) そして ``Element_Type`` に実行時の初期化を必要とする型が実引数として渡されることを防ぐ方法はありません。 その場合pragma ``Preelaborable_Initialization`` は破られます。 さて前回(:doc:`53日目 `)、``Preelaborable_Initialization`` がアスペクトとして書けるようになりました。 pragmaとアスペクトの違いは値を持つことです。 名前だけ書かれているように見えても実際には ``=> True`` が省略されています。 ``Boolean`` 型の値を持つということは論理式が書けます。 というわけで、今度は型が ``Preelaborable_Initialization`` かどうかを属性の形で取得できるようになりました。 これで ``Nonblocking`` 等と同様に仮引数を参照して切り替えることができるようになりました。 .. code-block:: ada generic type Element_Type is private; -- 省略 package Ada.Containers.Bounded_Doubly_Linked_Lists is -- 省略 type List is private with Preelaborable_Initialization => Element_Type'Preelaborable_Initialization, -- 省略 .. container:: gray-and-small 私も考えてみました。 ``Root_Storage_Pool`` がPreelaborable_Initializationになることは確定していました(:doc:`35日目 `\ を参照)ので、専用のストレージプールを作って抱え込めば ``Element_Type`` の初期化を実際に ``Append`` 等が呼ばれるまで遅らせることができます。 ``Adjust`` をどうやって実装するかが難しいですね……。 割り当て済みの領域を ``Element_Type`` にキャストして再代入すれば間接に ``Element_Type`` の ``Adjust`` を呼ぶことはできると思いますが、1回の代入で2回のコピーが必要になります。 Bounded版コンテナに本来不要な終了処理も必要になり、効率は悪いですね。 こうすれば実装できそうというだけです。 ただこうでもしないと実装できないはずの ``Bounded_Indefinite_Holders`` のAI(`AI12-0254-1`_)を見ますと実装依存の最適化に期待するようなことが書かれてまして、GNATに ``Bounded_Indefinite_Holders`` が実装される時にはこれらを効率的に実装できるような拡張を期待していいんでしょうね? "=" 演算子が隠されている場合のgeneric中の動作 --------------------------------------------- 型引数の(unlimitedな)抽象型には ``"="`` 演算子が付いてきます。 .. code-block:: ada generic type T2 is private; package Gen is function F (Left, Right : T2) return (Left = Right); -- "=" を使用 end Gen; ところがこのようなgenericはプリミティブな ``"="`` 演算子を禁止した型でもインスタンス化できてしまいます。 .. code-block:: ada type T3 is new Integer; function "=" (Left, Right : T3) return Boolean is abstract; package P is new Gen (T3); この時の動作が明確化されました。 実引数が基本型か基本型の配列の時は(``in`` 演算子同様に)既定義の ``"="`` が使用されます。 実引数が複合型の時はコンパイルエラーまたは ``Program_Error`` になります。 基本型の ``"="`` 演算子はユーザー定義しても既定義のものが使われる場面が多々あって信用なりませんね……。 pragmaからアスペクトへの書き換え -------------------------------- パッケージの種類を表す ``Pure`` や ``Preelaborate`` 等が全面的にアスペクトに書き換えられるようです。 その他特記事項 -------------- 変数のqualified式のrenamesはエラーになるようになりました。 :doc:`53日目 `\ を参照。 これは非互換になるとTucker先生が指摘されたようです。 AIそのものも前回からこの非互換を反映して修正されています。 :doc:`非互換性 `\ に追記しました。 他には、abstract型のプリミティブの ``Pre'Class`` からabstract関数を呼べるようになる修正が採択されています。 AI自体がまだ修正されそうですので紹介は次に回したいと思います。 その他文面等の修正 ------------------ 例によって文面等の修正やglossary(用語集)へ単語の追加が行われています。 大きい変更としては「null procedure」と「expression function」の使われ方が、宣言のみとされました。 普通のサブプログラムのように宣言されbody側で ``is null;`` としたものは「null procedure」に対する様々なルールの適用外ということが明確になります。 関連AI ------ - `AI12-0402-1`_ **Master of a function call with elementary result type** - `AI12-0404-1`_ **Presentation issues from Draft 26 review** - `AI12-0405-1`_ **Fixups for stable properties** - `AI12-0406-1`_ **Clarifying static accessibility** - `AI12-0407-1`_ **Fixups from Draft 26 review - part 1** - `AI12-0408-1`_ **Definition of “null procedure” and “expression function”** - `AI12-0409-1`_ **Preelaborable_Initialization and Bounded Containers** - `AI12-0413-1`_ **Reemergence of "=" when defined to be abstract** - `AI12-0414-1`_ **Replace categorization pragmas with aspects** .. _`AI12-0402-1`: http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0402-1.txt .. _`AI12-0404-1`: http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0404-1.txt .. _`AI12-0405-1`: http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0405-1.txt .. _`AI12-0406-1`: http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0406-1.txt .. _`AI12-0407-1`: http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0407-1.txt .. _`AI12-0408-1`: http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0408-1.txt .. _`AI12-0409-1`: http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0409-1.txt .. _`AI12-0413-1`: http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0413-1.txt .. _`AI12-0414-1`: http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0414-1.txt .. _`AI12-0254-1`: http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0254-1.txt