代码之家  ›  专栏  ›  技术社区  ›  Steve314

使用offsetof有什么问题?

  •  20
  • Steve314  · 技术社区  · 14 年前

    我在MIWW 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)
    

    这个问题似乎很熟悉——我想这是我以前试图解决的问题,但不久前失败了。代码在VisualC++中建立得很好,但是我最近还没有在任何其他编译器中构建这个特定的代码。

    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 parameter types are sometimes non-POD, so GCC classes c_Test 正如非POD和投诉(以及投诉和投诉-我收到了近800条警告线)。

    This is naughty by the strict wording of the standard, since non-POD types can break 抵销 . However, this kind of non-POD shouldn't be a problem in practice - C检验 will not have a virtual table, and no run-time trickery is needed to find the offset of m_Test .

    Besides, even if C检验 有了一个虚拟表,gcc使用一个内部函数来实现offsetof宏,该内部函数总是在编译时根据特定类型的静态布局进行计算。提供一个工具,然后每次使用它都抱怨(对不起,警告),这看起来很愚蠢。

    而且,我不是唯一一个在这里做这种事情的人…

    Answer to legit-uses-of-offsetof question

    记住有问题 抵销 因为这种原因,但我没有 认为

    有什么想法吗?

    1 回复  |  直到 12 年前
        1
  •  34
  •   Steve314    12 年前

    哎呀。。。

    问题 c_Test 由于T型为非POD,结构为非POD。下面是GCC手册中的一句话…

    -(C++和Objul-C++)的WNO无效偏移

    禁止应用警告 __offsetof_稹macro to a non-pod type.

    standard, applying ‘offsetof’ to a 未定义非pod类型。现有的 然而,C++实现 __offsetof_秷秷通常会提供有意义的 即使应用于某些 各种非POD类型。(如A) simple ‘struct’ that fails to be a POD 仅通过具有 构造函数。)此标志用于用户 他们知道自己在写作 不可移植的代码 故意选择忽略 警告。

    对“离岸”的限制可能是 在未来版本的C++中轻松 标准。

    我的问题是,几乎所有的T类型都有构造函数,因此被归为非pod类。我之前忽略了这一点,因为这是不相关的——当然,原则上,这应该与离岸无关。问题是,C++标准使用了一个POD与非POD分类,即使有许多不同的方式是非POD,编译器是正确的警告非标准兼容使用默认情况下。

    我目前的解决方案是选择上面的选项来禁止警告-现在我只需要找出如何告诉cmake使用它。