22

MinGW GCC 4.4.0 でいくつかの c++ コードをコンパイルしていますが、次の形式で警告が表示されます...

warning: invalid access to non-static data member '<membername>'  of NULL object
warning: (perhaps the 'offsetof' macro was used incorrectly)

この問題はおなじみのようです。以前に解決しようとして失敗したものだと思いますが、少し前です。このコードは Visual C++ で問題なくビルドできますが、この特定のコードを他のコンパイラで最近ビルドしたことはありません。

問題のコードは次のテンプレートです...

template<typename T>
class c_Align_Of
{
  private:
    struct c_Test
    {
      char m_Char;
      T    m_Test;
    };
  public:
    enum { e_Align = offsetof (c_Test, m_Test) };
};

明らかに、条件付きコンパイルを使用して、これにコンパイラ固有の関数を使用できます。また、C++0x によって (最終的に) 冗長になると思います。しかし、いずれにせよ、この の使用に問題は見当たりませんoffsetof

非常に衒学的なことですが、Tパラメーターの型が非 POD である場合があるため、GCC クラスc_Testが非 POD であり、不平を言う可能性があります (そして、不平を言い、不平を言う - 私はこれらの警告を 800 行近く受け取っています)。

非 POD 型は壊れる可能性があるため、これは標準の厳密な表現では不適切offsetofです。ただし、この種の非 POD は実際には問題にならないはずですc_Test。仮想テーブルはなく、 のオフセットを見つけるために実行時の策略は必要ありませんm_Test

さらに、c_Test仮想テーブルがあったとしても、GCC は、その特定の型の静的レイアウトに基づいてコンパイル時に常に評価される組み込み関数を使用して、offsetof マクロを実装します。ツールを提供し、それが使用されるたびに泣き言を言うのはばかげているように思えます。

また、このようなことをするのは私だけではありません...

オフセットの正当な使用に関する質問への回答

このような理由で に問題があったことは覚えていますが、問題はこのテンプレートではなかった思いますoffsetof

何か案は?

4

1 に答える 1

36

おっとっと...

問題c_Test、T 型が非 POD であるため、構造体が非 POD であることです。これはGCCマニュアルからの引用です...

-Wno-invalid-offsetof (C++ および Objective-C++ のみ)

'offsetof' マクロを非 POD タイプに適用することによる警告を抑制します。

1998 年の ISO C++ 標準によると、'offsetof' を非 POD 型に適用することは定義されていません。ただし、既存の C++ 実装では、'offsetof' は通常、特定の種類の非 POD 型に適用された場合でも意味のある結果をもたらします。(コンストラクターがあるという理由だけで POD 型にならない単純な「構造体」など。) このフラグは、移植性のないコードを書いていることを認識しており、それに関する警告を意図的に無視することを選択したユーザー向けです。

「offsetof」の制限は、C++ 標準の将来のバージョンで緩和される可能性があります。

私の問題は、ほとんどすべての T 型にコンストラクターがあるため、非 POD として分類されることです。私はこの点を以前は無関係だと無視しました - そしてもちろん、それは原則として offsetof には無関係であるべきです。問題は、C++ 標準では、非 POD となる方法がいくつかあるにもかかわらず、1 つの POD と非 POD の分類を使用していることです。コンパイラは、標準に準拠していない使用についてデフォルトで正しく警告します。

現時点での私の解決策は、警告を抑制するための上記のオプションです。これを使用するようにcmakeに指示する方法を理解する必要があります。

于 2010-06-28T06:06:15.660 に答える