这种使用offsetof有什么问题吗?
我正在 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
有一个问题,但我不认为问题出在这个模板上。
有什么想法吗?
I'm compiling some c++ code in MinGW GCC 4.4.0, and getting warnings with the following form...
warning: invalid access to non-static data member '<membername>' of NULL object
warning: (perhaps the 'offsetof' macro was used incorrectly)
This problem seems familiar - something I've tried to resolve before and failed, I think, but a while ago. The code builds fine in Visual C++, but I haven't built this particular code recently in any other compiler.
The problem code is the following template...
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) };
};
Obviously I can probably use some conditional compilation to use compiler-specific functions for this, and I believe C++0x will (at long last) make it redundant. But in any case, I cannot see anything wrong with this use of offsetof
.
Very pedantically, it's possible that because the T
parameter types are sometimes non-POD, so GCC classes c_Test
as non-POD and complains (and complains and complains - I'm getting nearly 800 lines of these warnings).
This is naughty by the strict wording of the standard, since non-POD types can break offsetof
. However, this kind of non-POD shouldn't be a problem in practice - c_Test
will not have a virtual table, and no run-time trickery is needed to find the offset of m_Test
.
Besides, even if c_Test
had a virtual table, GCC implements the offsetof macro using an intrinsic that is always evaluated at compile-time based on the static layout of that particular type. Providing a tool then whining (sorry, warning) every time it's used just seems silly.
Also, I'm not the only person around here who does this kind of thing...
Answer to legit-uses-of-offsetof question
I do remember having an issue with offsetof
for this kind of reason, but I don't think the problem was this template.
Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
糟糕...
问题是由于 T 类型不是 POD,所以
c_Test
结构不是 POD。这是 GCC 手册中的引用...我的问题是几乎所有 T 类型都有构造函数,因此被归类为非 POD。我之前忽略了这一点,因为它无关紧要——当然原则上它应该与 offsetof 无关。问题在于,C++ 标准使用一种 POD 与非 POD 分类,尽管有许多不同的方式可以成为非 POD,并且默认情况下编译器会正确地警告不符合标准的使用。
我目前的解决方案是上面的选项来抑制警告 - 现在我只需要弄清楚如何告诉 cmake 使用它。
Oops...
The issue is with the
c_Test
struct being non-POD due to the T type being non-POD. Here's a quote from the GCC manual...My problem is that almost all my T types have constructors, and are therefore classed as non-POD. I ignored this point as irrelevant earlier - and of course it should be irrelevant for offsetof in principle. The trouble is that the C++ standard uses the one POD vs. non-POD classification even though there are a number of distinct ways to be non-POD, and the compiler is correct to warn about non-standards-compliant use by default.
My solution for the moment will be the option above to suppress the warning - now I just need to figure out how to tell cmake to use it.