这种使用offsetof有​​什么问题吗?

发布于 2024-09-07 14:46:45 字数 1339 浏览 6 评论 0原文

我正在 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问题的答案

确实记得由于这种原因,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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

桃气十足 2024-09-14 14:46:45

糟糕...

问题是由于 T 类型不是 POD,所以 c_Test 结构不是 POD。这是 GCC 手册中的引用...

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

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

根据 1998 ISO C++
标准,将“offsetof”应用于
非 POD 类型未定义。在现有的
然而,C++ 实现
'offsetof' 通常给出有意义的
即使应用于某些特定的结果
各种非 POD 类型。 (比如一个
简单的“结构”无法成为 POD
类型仅凭借具有
构造函数。)该标志供用户使用
谁知道自己正在写作
不可移植的代码以及谁拥有
故意选择忽略
对此发出警告。

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

我的问题是几乎所有 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...

-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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文