这个使用offsetof有什么问题? [英] What is wrong with this use of offsetof?
问题描述
我在MinGW GCC 4.4.0中编译一些c ++代码,并获得以下形式的警告...
警告:无效访问NULL对象的非静态数据成员< membername>
pre>
警告:(可能offsetof宏使用不正确)
这个问题似乎很熟悉 - 我之前试图解决的问题,但我想,但是不久以前。该代码在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宏,该内部在编译时总是基于该特定类型的静态布局进行评估。
此外,我不是这里唯一一个做这种事情的人。 ...
我 code> offsetof 这样的原因,但我不是 问题是这个模板。
任何想法?
解决方案糟糕...
由于T类型是非POD,因此的问题是,其中
c_Test
结构是非POD。
-Wno-invalid-offsetof(仅限C ++和Objective-C ++)
禁止将
'offsetof'宏应用于非POD类型的警告。
根据1998年ISO C ++
标准,将'offsetof'应用于
非POD类型是未定义的。然而,在现有的
C ++实现中,即使应用于某些
种非POD类型,
'offsetof'通常也会产生有意义的
结果。 (例如一个
简单的'struct'不能成为一个POD
类型只是凭借一个
构造函数。)这个标志是为用户
谁知道他们正在编写
非便携代码,并且有
故意选择忽略
警告。
'offsetof'的限制可能
我的问题是,几乎所有的T类型具有构造函数,因此被归类为非POD。我忽略了这一点作为不相关的更早 - 当然它应该是不重要的offsetof在原则上。麻烦的是,C ++标准使用一个POD与非POD分类,即使有许多不同的方式是非POD,并且编译器是正确的,警告默认情况下不符合标准的使用。 / p>
我现在的解决方案将是上面的选项来抑制警告 - 现在我只需要弄清楚如何告诉cmake使用它。
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 classesc_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 ofm_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?
解决方案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...-Wno-invalid-offsetof (C++ and Objective-C++ only)
Suppress warnings from applying the ‘offsetof’ macro to a non-POD type.
According to the 1998 ISO C++ standard, applying ‘offsetof’ to a non-POD type is undefined. In existing C++ implementations, however, ‘offsetof’ typically gives meaningful results even when applied to certain kinds of non-POD types. (Such as a simple ‘struct’ that fails to be a POD type only by virtue of having a constructor.) This flag is for users who are aware that they are writing nonportable code and who have deliberately chosen to ignore the warning about it.
The restrictions on ‘offsetof’ may be relaxed in a future version of the C++ standard.
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.
这篇关于这个使用offsetof有什么问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!