我正在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
出现问题,但我认为问题就是这个模板。
有什么想法吗?
答案 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使用它。