使用offsetof有​​什么问题?

时间:2010-06-28 03:35:32

标签: 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)

这个问题似乎很熟悉 - 我想,之前我试图解决这个问题,但是我想,但不久之前。代码在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宏,该内部函数始终在编译时根据该特定类型的静态布局进行求值。提供一个工具,然后每次使用时抱怨(抱歉,警告)似乎很愚蠢。

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

Answer to legit-uses-of-offsetof question

因为这种原因而记得offsetof出现问题,但我认为问题就是这个模板。

有什么想法吗?

1 个答案:

答案 0 :(得分:34)

糟糕...

问题c_Test结构是非POD,因为T类型是非POD。以下是GCC手册的引用......

  

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

     

禁止应用警告   'offsetof'宏到非POD类型。

     

根据1998 ISO C ++   标准,将'offsetof'应用于a   非POD类型未定义。在现有的   但是,C ++实现   'offsetof'通常有意义   结果即使应用于某些   各种非POD类型。 (比如一个   简单的'struct'无法成为POD   只有通过拥有一个类型   构造函数。)此标志供用户使用   谁知道他们正在写作   不可移植的代码和谁有   刻意选择忽略了   关于它的警告。

     

对'offsetof'的限制可能是   在未来版本的C ++中放松   标准。

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

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