Ada 202x (追記2) - 非互換性¶
Ada 202xで挙動が変わるコードの考察。 引き続きこのページも妄想でできています。
コンパイルエラーになるもの¶
予約語¶
新しい予約語 parallel
を使っていた場合はエラーになります。
declare
type Port_Type is (Serial, Parallel); -- error
識別子の衝突¶
use
または use all type
しているライブラリに新しく追加されたエンティティの識別子が衝突する可能性があります。
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
が見えるようになったために衝突する場合もあると思われます。
45日目を参照。
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
の中でグローバル変数を宣言していた場合エラーになります。
43日目を参照。
既存の処理系でもほぼエラーになっていたと思います。
genericのin引数をrenames¶
generic
の in
引数を renames
する場合 not null
が一致していなかったらエラーになります。
42日目を参照。
ドット記法をrenames¶
ドット記法を renames
していた場合、オブジェクト名部分が renames
不可能だったらエラーになります。
41日目を参照。
Qualified式をrenames¶
変数のqualified式を renames
していた場合、qualified式の型が変数の型より狭い subtype
だったらエラーになります。
53日目を参照。
抽象型のin式¶
ユーザー定義の "="
演算子を持つ抽象型で実体が基本型の場合、実体が可視の箇所からin式を使用しているとエラーになります。
41日目を参照。
抽象型のaccess型の引数を持つプリミティブ¶
型の本体がtagged型だった場合 not null
がなければエラーになります。
42日目を参照。
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型からの暗黙の型変換で生存期間のチェックが行われるようになったため違反していればエラーになります。 42日目を参照。
record内の匿名のaccess型¶
record
内の匿名のaccess型が外側の record
の Convention
を引き継ぐようになりましたのでデフォルトの Convention => Ada
を期待していた箇所でエラーになります。
42日目を参照。
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
を期待していた箇所でエラーになります。
42日目を参照。
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
内のデフォルト引数や事前条件で内部呼び出しを行っていた場合エラーになります。
39日目を参照。
protectedとclass-wideアスペクト¶
protected
内でclass-wideアスペクトを指定していたらエラーになります。
39日目を参照。
アスペクト¶
自己参照していたらエラーになります。 45日目を参照。
抽象型に内部表現が指定されていたらエラーになります。 45日目を参照。
Constant_Indexing/Variable_Indexing¶
片方だけ指定しておいて派生先でもう片方を指定したり、interface
に指定しておいて派生先で衝突したりすればエラーになります。
41日目を参照。
Ada 2012からあるアスペクトでは Default_Iterator
、 Implicit_Dereference
、 Iterator_Element
も同様です。
Remote_Call_Interface¶
'Read
/'Write
属性をユーザー定義していたらエラーになります。
45日目を参照。
pragma Conflict_Check_Policy¶
Ada 202xでは変数へのアクセスの競合がコンパイル時にチェックされます。 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
に変わりました。
挙動も絶対時刻メインから相対時刻メインへと変更されています。
31日目を参照。
pragma Restrictions (No_IO)¶
No_IO
に Ada.Directories
が含まれるようになりましたので No_IO
を指定していながら Ada.Directories
を使っているコードがエラーになります。
33日目を参照。
Ada.Containers.Vectors.Append, Prepend, Insert¶
Append
、 Prepend
、 Insert
で Vector
を追加していたコードは Append_Vector
、 Prepend_Vector
、 Insert_Vector
に書き換える必要があります。
53日目を参照。
挙動が変わるもの¶
universal_integerの範囲エラー¶
実行時にuniversal_integerがroot_integerの範囲を超えたら Constraint_Error
になります。
44日目を参照。
universal_realも同様にroot_realの範囲を超えたら Constraint_Error
になります。
Unchecked_Unionのin式¶
unconstrained in
unconstrained |
constrainedの形の式があった場合評価順に関わらず Program_Error
になるようになりました。
41日目を参照。
protectedの遅延初期化¶
protected
の要素に遅延初期化のルールが適用されるようになりましたので初期化順が変わるかもしれません。
40日目を参照。
requeue文とAccessibility_Check¶
requeue
文で実行時に Accessibility_Check
が行われるようになったため偶々クラッシュ等せずに運良く動いていたコードが実行時エラーになるかもしれません。
38日目を参照。
predicateのチェックタイミング¶
デフォルト初期化でもpredicateがチェックされるようになりましたので Default_Value
とpredicateが矛盾していたのを見逃されていたコードがあれば実行時エラーになるかもしれません。
38日目を参照。
また未初期化変数を out
パラメータに渡した場合にはpredicateもチェックされなくなりましたので例外の発生を期待していたコードがあれば挙動が変わるかもしれません。
(ないだろjk。)
pragma Assertion_Policy¶
pragma Assertion_Policy
が標準ライブラリの中まで影響を及ぼさなくなりましたのでこれまで抑制できていたチェックが抑制できなくなって挙動が変わるかもしれません。
37日目を参照。
pragma Restrictions (No_Dynamic_Attachment)¶
No_Dynamic_Attachment
を指定していた場合同じ割り込み番号に複数のハンドラがあると Program_Error
になります。
33日目を参照。
処理系依存のもの¶
文字列の正規化¶
もしソースコードをNFKC正規化していた処理系であれば、文字列に許されている正規化がNFKCからNFCに変わったことでコンパイル結果の文字列が変化するかもしれません。 34日目を参照。 (そのような処理系が実在するかは不明です。)
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 に良くまとまっています。