You've suddenly introduced some new, unrealistic constraints.
How so? In my container library, why would some other code be creating
nodes that inherit my private node type? That would be absurd.
These are the exact constraints I described from the start.
The offsetof is used to pick out the positions of certain fields in a
struct that I control, and placed in a closure-like data block, so
that data-driven non-typesafe code can find those fields. The struct
is defined as a private detail in a thin template wrapper.
Nodes are created. Nodes are accessed. Nodes are modified. Nodes are
destroyed. For any one wrapper class, they are all the same damn node
type - or at worst, minor variants with a shared header.
The node may be non-POD because the type specified by the application
as a template parameter for the contained data may be non-POD. This
*should* be completely irrelevant to offsetof.
Do I need to describe this again?
I gave one in another posting. You've just said above (for the
first time) that you're not interested in that case.
Crap - you just didn't read it properly.
The standard can't be based on such things. If the standard
says it works, then it has to work.
The layout is dynamic. It depends on the context where the
class is used. You can't get around that by saying you don't
want to consider such contexts.
class M isn't class D - they are different classes, irrespective of
the fact that one inherits the other. The layout for either one is
fixed.
As for not considering your irrelevant contexts, what the hell do you
expect. Inheritance has nothing to do with offsetof. To offsetof, any
struct or class is just itself - not a representative of a family.
Just as it always was.
Why the hell should I consider your invented fantasy issues?
Of course if someone is confusing the term "offset" with "member"...
Let me give you a clue. The word offset refers to the layout of the
struct/class. That is *all* it refers to. Any assumptions about that
offset mapping to any particular field in some other struct are
obviously the programmers responsibility, just as they always were,
and I'm not making *ANY* such assumptions. Inheritance would be just
another way to define that some other struct, but no-one gets the
chance to inherit the thing anyway. Any inheritance issues are purely
restricted to fields that takes application specified types, and
frankly should be none of the containers business.
The situation WRT the data structure node is - or at least should be -
exactly the same as it always was, irrespective of non-PODness
propogating up from member field to node struct.
It's not nondeterminism, but it does depend on the context in
which the class is used. Given the arguments to offsetof, the
compiler does not have enough information to determine that
context.
No it doesn't, because we are talking about a field within a known
struct, not within an instance of some unknown dynamically-accessed
struct. We always were right from the start. Its all we *could* have
been talking about, since offsetof doesn't know *ANYTHING* about
instances at all - it only ever sees types and field-names.
I only need offsetof to do the basic job that offsetof always did. I
don't need all the overengineered crap that's built into member
pointers, and neither does anyone else. If they had worked when I had
needed them I would have used them anyway, but they didn't.
All I require of offsetof is what it was always meant to do - give me
the offset of a known visible field within the fixed layout of a known
struct. The only "new" C++-specific thing is that the struct might
happen to have non-POD fields (due to app-specified types from
template parameters), and therefore the struct as a whole might happen
to be non-POD for that (and only that) reason.
In practice, of course, it should be perfectly possible to define my
node structs using multiple and virtual inheritance if I feel like it.
It makes no difference in principle - offsetof is still looking for a
known visible field in a known struct with a fixed layout. I wouldn't
*assume* it's possible because I know how the traditional macro form
worked.
But even for that, lets face it - most people would call virtual
inheritance a niche tool at best, and possibly another failed
experiment. What was done is to break offsetof for *all* cases of
non-POD however it arises, just to support virtual inheritance without
tweaking the offsetof implementation or even just stating "not if the
type inherits any virtual base, directly or indirectly" which took me
all of five seconds to write.
By the way, this "never used" offsetof is scattered throughout the
Microsoft libraries like confetti. Also, I popped over to
http://www.koders.com/, but I figured I didn't much feel like
searching through the 1,133 results - on a quick skim, some obviously
aren't genuine uses, but some equally obviously are. That's for C++,
not C.
Genuine uses occur in applications like Blender, in framework code
such as some marshalling stuff, in Boost and more.
Seems like offsetof is used. Not a huge amount of course - but any
"it's not needed because it's not used" argument is pure BS.
Oh, and that Boost example is a container. bidirectional_map to be
specific. And guess what - the offsetof parameter is a type that's
dependent on template parameters, which could easily be non-POD.
Well, I say "that Boost example", but there are several other examples
in Boost. Just pop over to Koders and do a search.
In other words Boost is doing exactly what I do. Wow. Boost
contributors doing precisely the same "no-one does that" thing that I
do. What a shock.
What the hell. You'll never admit to being wrong anyway, so what's the
point.
*PLONK*