Ada 202x (追記2) - 非互換性 =========================== .. post:: Jan 17, 2020 00:00:00 :tags: ada, ada_2022 .. |ZWSP| unicode:: U+200B .. ZERO WIDTH SPACE :trim: Ada 202xで挙動が変わるコードの考察。 引き続きこのページも妄想でできています。 コンパイルエラーになるもの -------------------------- 予約語 ++++++ 新しい予約語 ``parallel`` を使っていた場合はエラーになります。 .. code-block:: ada declare type Port_Type is (Serial, Parallel); -- error 識別子の衝突 ++++++++++++ ``use`` または ``use all type`` しているライブラリに新しく追加されたエンティティの識別子が衝突する可能性があります。 .. code-block:: ada declare package Pkg1 is package Stable is ZZZ : Integer; end Stable; end Pkg1; package Float_Vectors is new Ada.Containers.Vectors (Positive, Float); use Pkg1; use Float_Vectors; package Alias renames Stable; -- error ZZZ : Integer renames Alias.ZZZ; 似たような話では ``private procedure`` の仕様部から親パッケージの ``private with`` が見えるようになったために衝突する場合もあると思われます。 :doc:`45日目 `\ を参照。 .. code-block:: ada package Lib1 is subtype T is Integer; end Lib1; package Lib2 is subtype T is Float; end Lib2; with Lib1; private with Lib2; package Parent is use Lib1; private use Lib2; end Parent; private procedure Parent.Child (Argument : T); -- error Pureパッケージ内のgeneric内のグローバル変数 +++++++++++++++++++++++++++++++++++++++++++ ``Pure`` パッケージ内にネストされた ``generic`` の中でグローバル変数を宣言していた場合エラーになります。 :doc:`43日目 `\ を参照。 既存の処理系でもほぼエラーになっていたと思います。 genericのin引数をrenames ++++++++++++++++++++++++ ``generic`` の ``in`` 引数を ``renames`` する場合 ``not null`` が一致していなかったらエラーになります。 :doc:`42日目 `\ を参照。 ドット記法をrenames +++++++++++++++++++ ドット記法を ``renames`` していた場合、オブジェクト名部分が ``renames`` 不可能だったらエラーになります。 :doc:`41日目 `\ を参照。 Qualified式をrenames ++++++++++++++++++++ 変数のqualified式を ``renames`` していた場合、qualified式の型が変数の型より狭い ``subtype`` だったらエラーになります。 :doc:`53日目 `\ を参照。 抽象型のin式 ++++++++++++ ユーザー定義の ``"="`` 演算子を持つ抽象型で実体が基本型の場合、実体が可視の箇所からin式を使用しているとエラーになります。 :doc:`41日目 `\ を参照。 抽象型のaccess型の引数を持つプリミティブ ++++++++++++++++++++++++++++++++++++++++ 型の本体がtagged型だった場合 ``not null`` がなければエラーになります。 :doc:`42日目 `\ を参照。 .. code-block:: ada package Pkg2 is type T is private; procedure Primitive (Object : access T); -- error private type T is tagged null record; end Pkg2; Ada 95の頃はこのようなコードは沢山書かれていました。 匿名のaccess型からの暗黙の型変換 ++++++++++++++++++++++++++++++++ 匿名のaccess型からの暗黙の型変換で生存期間のチェックが行われるようになったため違反していればエラーになります。 :doc:`42日目 `\ を参照。 record内の匿名のaccess型 ++++++++++++++++++++++++ ``record`` 内の匿名のaccess型が外側の ``record`` の ``Convention`` を引き継ぐようになりましたのでデフォルトの ``Convention => Ada`` を期待していた箇所でエラーになります。 :doc:`42日目 `\ を参照。 .. code-block:: ada declare type T is record Callback : not null access procedure; end record with Convention => Fortran; procedure Ada_Proc is null; Item : T := (Callback => Ada_Proc'Access); -- error protected内の匿名のaccess型 +++++++++++++++++++++++++++ ``protected`` 内の匿名の ``access procedure`` が ``access protected procedure`` ではなく他と同じになりましたので ``access protected procedure`` を期待していた箇所でエラーになります。 :doc:`42日目 `\ を参照。 .. code-block:: ada declare protected Prot1 is procedure High_Order (Callback : not null access procedure); end Prot1; protected Prot2 is procedure Callback; end Prot2; -- Prot1とProt2の実装は省略 begin Prot1.High_Order (Prot2.Callback'Access); -- error ``protected`` を書き足す必要があります。 protected内のデフォルト引数 +++++++++++++++++++++++++++ ``protected`` 内のデフォルト引数や事前条件で内部呼び出しを行っていた場合エラーになります。 :doc:`39日目 `\ を参照。 protectedとclass-wideアスペクト +++++++++++++++++++++++++++++++ ``protected`` 内でclass-wideアスペクトを指定していたらエラーになります。 :doc:`39日目 `\ を参照。 アスペクト ++++++++++ 自己参照していたらエラーになります。 :doc:`45日目 `\ を参照。 抽象型に内部表現が指定されていたらエラーになります。 :doc:`45日目 `\ を参照。 Constant_Indexing |ZWSP| /Variable_Indexing +++++++++++++++++++++++++++++++++++++++++++ 片方だけ指定しておいて派生先でもう片方を指定したり、``interface`` に指定しておいて派生先で衝突したりすればエラーになります。 :doc:`41日目 `\ を参照。 Ada 2012からあるアスペクトでは ``Default_Iterator`` 、 ``Implicit_Dereference`` 、 ``Iterator_Element`` も同様です。 Remote_Call_Interface +++++++++++++++++++++ ``'Read``/``'Write`` 属性をユーザー定義していたらエラーになります。 :doc:`45日目 `\ を参照。 pragma Conflict_Check_Policy ++++++++++++++++++++++++++++ Ada 202xでは変数へのアクセスの競合がコンパイル時にチェックされます。 :doc:`18日目 `\ を参照。 私の探し方が悪いのかpragma ``Conflict_Check_Policy`` のデフォルトを見つけられませんでした。 恐らく処理系のスイッチで変えられるようになるとは思います。 そうしますと、処理系の設定次第でこれまで通っていたコードがエラーになる可能性があります。 実際には問題のないコードの場合は ``pragma Conflict_Check_Policy (No_Tasking_Conflict_Checks);`` を書き足して回避できます。 pragma Task_Dispatching_Policy (EDF_Across_Priorities) ++++++++++++++++++++++++++++++++++++++++++++++++++++++ ``EDF_Across_Priorities`` は ``EDF_Within_Priorities`` に変わりました。 挙動も絶対時刻メインから相対時刻メインへと変更されています。 :doc:`31日目 `\ を参照。 pragma Restrictions (No_IO) +++++++++++++++++++++++++++ ``No_IO`` に ``Ada.Directories`` が含まれるようになりましたので ``No_IO`` を指定していながら ``Ada.Directories`` を使っているコードがエラーになります。 :doc:`33日目 `\ を参照。 Ada.Containers.Vectors.Append, Prepend, Insert ++++++++++++++++++++++++++++++++++++++++++++++ ``Append`` 、 ``Prepend`` 、 ``Insert`` で ``Vector`` を追加していたコードは ``Append_Vector`` 、 ``Prepend_Vector`` 、 ``Insert_Vector`` に書き換える必要があります。 :doc:`53日目 `\ を参照。 挙動が変わるもの ---------------- universal_integerの範囲エラー +++++++++++++++++++++++++++++ 実行時にuniversal_integerがroot_integerの範囲を超えたら ``Constraint_Error`` になります。 :doc:`44日目 `\ を参照。 universal_realも同様にroot_realの範囲を超えたら ``Constraint_Error`` になります。 Unchecked_Unionのin式 +++++++++++++++++++++ unconstrained ``in`` unconstrained ``|`` constrainedの形の式があった場合評価順に関わらず ``Program_Error`` になるようになりました。 :doc:`41日目 `\ を参照。 protectedの遅延初期化 +++++++++++++++++++++ ``protected`` の要素に遅延初期化のルールが適用されるようになりましたので初期化順が変わるかもしれません。 :doc:`40日目 `\ を参照。 requeue文とAccessibility_Check ++++++++++++++++++++++++++++++ ``requeue`` 文で実行時に ``Accessibility_Check`` が行われるようになったため偶々クラッシュ等せずに運良く動いていたコードが実行時エラーになるかもしれません。 :doc:`38日目 `\ を参照。 predicateのチェックタイミング +++++++++++++++++++++++++++++ デフォルト初期化でもpredicateがチェックされるようになりましたので ``Default_Value`` とpredicateが矛盾していたのを見逃されていたコードがあれば実行時エラーになるかもしれません。 :doc:`38日目 `\ を参照。 また未初期化変数を ``out`` パラメータに渡した場合にはpredicateもチェックされなくなりましたので例外の発生を期待していたコードがあれば挙動が変わるかもしれません。 (ないだろjk。) pragma Assertion_Policy +++++++++++++++++++++++ pragma ``Assertion_Policy`` が標準ライブラリの中まで影響を及ぼさなくなりましたのでこれまで抑制できていたチェックが抑制できなくなって挙動が変わるかもしれません。 :doc:`37日目 `\ を参照。 pragma Restrictions (No_Dynamic_Attachment) +++++++++++++++++++++++++++++++++++++++++++ ``No_Dynamic_Attachment`` を指定していた場合同じ割り込み番号に複数のハンドラがあると ``Program_Error`` になります。 :doc:`33日目 `\ を参照。 処理系依存のもの ---------------- 文字列の正規化 ++++++++++++++ もしソースコードをNFKC正規化していた処理系であれば、文字列に許されている正規化がNFKCからNFCに変わったことでコンパイル結果の文字列が変化するかもしれません。 :doc:`34日目 `\ を参照。 (そのような処理系が実在するかは不明です。) .. code-block:: ada begin Ada.Wide_Wide_Text_IO.Put ("㍉"); 今まで ``ミリ`` が出力されていた処理系でもAda 202xからは ``㍉`` になります。 挙動が決まっていなかったケース ++++++++++++++++++++++++++++++ 決まっていなかった挙動がAda 202xで定められた中で、処理系のこれまでの挙動がAda 202xと異なっていた場合は挙動が変わることになります。 ``Ada.Directories.Containing_Directory ("/")`` あたりが危険そうです。 注意 ---- Ada 2012 with Technical Corrigendum 1の変更は含めていません。 Technical Corrigendum 1でも契約関連で大きく修正されたり ``Pure`` 内でvariable viewを持つ ``constant`` が禁止されたりと結構大きな非互換がありますので見ておくといいと思います。 例によってJohn Barnes先生の `Rationale Update for Ada 2012`_ に良くまとまっています。 .. _`Rationale Update for Ada 2012`: http://www.ada-auth.org/standards/12rat/html/RCorr-TOC.html