Ada 2020 (29日目) - No_Controlled_Parts

細かい変更点まで見ていきましたら一向に終わりそうにないです。 怖い。 とりあえず新機能を紹介してしまうのが目標。

経緯

終了処理を必要としない型の保証が欲しくなるときありますよね。 C++で言えばtrivially destructibleです。

今までどうしていたか

かつてAda 83では有名な「no subset, no superset」という標語が掲げられていたこともありまして、Embedded C++みたいなものを作らせないためにも機能制限が必要ならばAda自身の機能でもって制限できるようにpragma Restrictions が用意されています。

ちなみにこの標語Ada 2005でやめたそうですよ。 Pascal Leroy先生の発言の記録が残っていました。 ちょっと衝撃ですねえ。

まあ実際Ada 95の時点で既に処理系ごとに拡張されまくってましたし。 GNATも大概ですがDEC Adaもすごそうです。 (DEC AdaはAda 95で止まってそう?)

標準の範囲ですと pragma Restrictions (No_Dependence => Ada.Finalization); でcontrolled型を禁止できます。

GNATであれば pragma Restrictions (No_Finalization);task 型等も含めて禁止できます。

ただ、このpragma Restrictions は困ったことにパーティション(雑なイメージとしては.exeや.dll)全体に影響します。 使い辛いです。

特定箇所だけ制限したい場合はライブラリとして切り出してpragmaを付けてコンパイルできるかテスト、みたいな手順が必要になります。

Ada 2020での改善

No_Controlled_Partsアスペクト

No_Controlled_Parts アスペクトが追加されました。 型が終了処理を必要としていたらエラーにしてくれます。

type T is
  record
     A : Some_Type;
     B : Another_Type;
     C : Abstract_Type;
     -- 沢山の宣言
     Z : Unknown_Type;
  end record
    with No_Controlled_Parts;

型ごとに終了処理を必要としない保証ができるようになりました。

関連AI

所感

これは便利です。

特に中で悪いことをする generic の引数としてcontrolled型等を渡されたくない場合に簡単に弾けるようになりました。

generic
   type T is private;
package Low_Level_Op is

   procedure memcpy
     (dst : not null access T;
      src : not null access constant T);
     -- This is danger!

private

   type Dummy_For_Restriction is
      record
         Element : T;
      end record
        with No_Controlled_Parts;

end Low_Level_Op;

強いて言えば値として取得してif文で使えればもっと便利でした。 今後更に強化されることを期待します。