tags:

views:

94

answers:

2

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?

EDIT

Some of the types that result in warnings are definitely POD in every way that makes sense, with all members being simple types like int.

A: 

Well the naive interpretation of this particular error is to take it at face value: You access a private field from inside an enum. But presumably, enums are static by definition (I suppose this is why working with enum constants is possible in the first place, they're essentially int constants with a fancy name).

The enum is a member of the class. Members of a class are allowed to reference private members of the same class, or else how could you ever use any private member? There's no data hiding issue here - but, well, see my (slightly embarrassing) answer, which should appear in a few minutes...
Steve314
+1  A: 

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 of course (the thing I wasn't taking into account), the compiler certainly isn't misbehaving by warning about non-standards-compliant use by default.

I'm still getting a strong sense of deja vu, BTW.

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.

Steve314
I feel guilty accepting this - maybe I should undo that and delete the question instead?
Steve314
Its fine as it really answers your question - others might make the same mistake. There is even a [badge](http://stackoverflow.com/badges/14/self-learner) that encourages this :)
Georg Fritzsche