1

「MaxAlign トリック」と呼ばれるものを示すLoki シングルトン実装のコード スニペットに従います。私はそれがアラインメントと関係があると思いますが(当たり前!)、ユニオン内で言及されているすべてのタイプとアラインしようとする目的は何ですか? それがないと中の新しい配置はCreate()壊れますか?

    template <class T> struct CreateStatic
    {
        union MaxAlign
        {
            char t_[sizeof(T)];
            short int shortInt_;
            int int_;
            long int longInt_;
            float float_;
            double double_;
            long double longDouble_;
            struct Test;
            int Test::* pMember_;
            int (Test::*pMemberFn_)(int);
        };

        static T* Create()
        {
            static MaxAlign staticMemory_;
            return new(&staticMemory_) T;
        }
        
        // other code...

  }

4

1 に答える 1

0

MaxAlign2 つの目的を果たします。まず、これは C++11 の実装ですstd::max_align_t: 「アラインメント要件が少なくともすべてのスカラー型と同じくらい厳密 (同じくらい大きい) である自明な標準レイアウト型」。( cppreference )。型のアラインメントは、アラインメント要件が最も高いデータ メンバーのアラインメントであるため、 の定義はMaxAlignまさにそれを示します。対象のプラットフォームのアライメント。

T第 2 に、これは:を格納するのに十分な大きさのバッファでもあります。

char t_[sizeof(T)];

両方の側面を考慮MaxAlignして、C++ 11 機能を提供しますstd::aligned_storage_t<size, alignment>(オーバーアラインメントをT考慮せずに - おそらく当時は存在すらしていませんでした)。

しかし、なぜそれが必要なのか: 配置newには、構築中のインスタンスに合わせてバッファーを適切に配置する必要があります。この「アライメント トリック」がないと、未定義の動作になる可能性があります。TLoki は unkonwn 型であるため、コードがコンパイルされているプラ​​ットフォームに合わせて最大のアライメントを選択することで、あらゆるリスクを回避します。

現代のコードでは、placement new はおそらく使用せずstatic、スタック上のオブジェクトを使用します。

static T& Create() {
    static T instance;
    return instance;
}

しかし、20 年前には、これは複数のコンパイラやマルチスレッド環境で適切に機能しなかった可能性があります (T instance上記の適切な初期化は、C++11 IIRC 以降でのみ保証されています)。

于 2022-02-22T15:38:30.507 に答える