这个使用offsetof有​​什么问题? [英] What is wrong with this use of offsetof?

查看:452
本文介绍了这个使用offsetof有​​什么问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在MinGW GCC 4.4.0中编译一些c ++代码,并获得以下形式的警告...

 警告:无效访问NULL对象的非静态数据成员< membername>
警告:(可能offsetof宏使用不正确)
pre>

这个问题似乎很熟悉 - 我之前试图解决的问题,但我想,但是不久以前。该代码在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宏,该内部在编译时总是基于该特定类型的静态布局进行评估。



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



回答legal-uses-of-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 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?

解决方案

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆