使用offsetof有​​什么问题?

Ste*_*314 20 c++ gcc gcc4

我正在编译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)
Run Code Online (Sandbox Code Playgroud)

这个问题似乎很熟悉 - 我想,之前我曾试图解决这个问题,但我想,但不久之前.代码在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) };
};
Run Code Online (Sandbox Code Playgroud)

显然,我可以使用一些条件编译来为此使用特定于编译器的函数,我相信C++ 0x(最后)会使它变得多余.但无论如何,我看不出这种用法有什么不妥offsetof.

非常迂腐,有可能因为T参数类型有时是非POD,所以GCC类c_Test作为非POD和抱怨(抱怨和抱怨 - 我得到近800行这些警告).

由于非POD类型可能会破坏,因此标准的严格措辞令人顽皮offsetof.但是,这种非POD在实践中应该不是问题 - c_Test不会有虚拟表,也不需要运行时技巧来查找偏移量m_Test.

此外,即使c_Test有一个虚拟表,GCC 也会使用内部函数实现offsetof宏,该内部函数总是在编译时根据该特定类型的静态布局进行求值.提供一个工具,然后每次使用时抱怨(抱歉,警告)似乎很愚蠢.

另外,我不是这里唯一一个做这种事的人......

回答合法使用偏移的问题

确实记得offsetof因为这种原因而遇到问题,但我不认为问题出在这个模板上.

有任何想法吗?

Ste*_*314 34

糟糕!

这个问题c_Test结构是非POD由于T类是非POD.以下是GCC手册的引用......

-Wno-invalid-offsetof(仅限C++和Objective-C++)

通过将'offsetof'宏应用于非POD类型来抑制警告.

根据1998 ISO C++标准,将'offsetof'应用于非POD类型是不确定的.然而,在现有的C++实现中,即使应用于某些类型的非POD类型,'offsetof'通常也会产生有意义的结果.(例如,只有通过构造函数才能成为POD类型的简单'struct'.)此标志适用于知道他们正在编写不可移植代码并且故意选择忽略有关它的警告的用户.

在未来版本的C++标准中,可以放宽对"offsetof"的限制.

我的问题是几乎所有的T类型都有构造函数,因此被归类为非POD.我之前忽略了这一点是无关紧要的 - 当然它原则上与偏移无关.问题是C++标准使用一个POD与非POD分类,即使有许多不同的方法是非POD,并且编译器在默认情况下警告不符合标准的使用是正确的.

我现在的解决方案将是上面的选项来抑制警告 - 现在我只需要弄清楚如何告诉cmake使用它.

  • 它很好,因为它真的回答了你的问题 - 其他人可能会犯同样的错误.甚至有一个[徽章](http://stackoverflow.com/badges/14/self-learner)鼓励这个:) (11认同)