Template technicality - What does the standard say?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Stephen Horne

    #16
    Re: Template technicality - What does the standard say?

    On Wed, 15 Oct 2008 16:39:32 +1300, Ian Collins <ian-news@hotmail.co m>
    wrote:
    >Stephen Horne wrote:
    >>
    >In my current circumstances, paying for the standard would mean not
    >eating for a week,
    >
    >You can live off $18 a week, I'm impressed.
    Not quite *that* tight, but 'live' is questionable anyway. That's not
    the price I saw for the standard (or the one James quoted).

    If that price is available, next problem is no credit card. I refuse
    to get one so long as I'm on benefits for obvious reasons.
    >A constraint that means C data structure code cannot be adapted and
    >wrapped in a C++ template? IIRC, one of the basic design principles of
    >C++ is that people should be able to adapt their C libraries without a
    >complete rewrite.
    >>
    >By definition, a C data structure is a POD struct, so you can use offsetof.
    template<typena me T>
    struct This_May_Not_Be _POD
    {
    T Because_This_Ma y_Not_Be_POD;
    };

    That's the whole point.

    Comment

    • Stephen Horne

      #17
      Re: Template technicality - What does the standard say?

      On Wed, 15 Oct 2008 16:30:54 +1300, Ian Collins <ian-news@hotmail.co m>
      wrote:
      >Stephen Horne wrote:
      >On Tue, 14 Oct 2008 15:58:15 -0700 (PDT), James Kanze
      ><james.kanze@g mail.comwrote:
      >>Sorry, but when virtual inheritance is involved, it's
      >>dynamically defined. At least with all of the compilers I know,
      >>and I don't think it's possible to implement it otherwise.
      >>
      >I'm sorry, but it's basic textbook. The compiler determines what is
      >inherited and places each inherited class at a particualar offset
      >within the derived class, as if it were member data (which it is).
      >>
      >This isn't true. See 9.2.12 and 10.0.5.
      The standard has already been quoted at me, but read James' point that
      I was replying too - this isn't about the standard, it's about all the
      compilers he knows and what he thinks is possible.

      I challenge you. First, define a class using *ANY* standard C++
      features you please - multiple inheritance and virtual inheritance
      included. Lets call this class TEST.

      Now, create two instances of TEST. Don't care where you instantiate so
      long as you aren't using any further inheritance - global, local,
      normal member, static member, anything. Placement new it if you think
      that'll make a difference. Just make sure you don't instance any
      derived classes - both must be instances of the exact same class, ie
      TEST.

      Now, show me a compiler - *ANY* compiler - that uses different memory
      layouts for those two instances.

      Basic science. The easiest way to prove that instances of a single
      class can be arranged differently in different cases is to provide an
      example, and I'm only asking for one.

      You won't find one. The layout of the class isn't dynamic. It may not
      be the same as the layout of any classes that inherit from it, but
      that's beside the point. Even multiple inheritance would break offsets
      if you're looking at derived classes.

      Can you imagine what it would be like if one instance of a class was
      arranged differently to another instance of that exact same class? Can
      you imagine any vaguely coherent reason why a compiler-writer would
      choose to introduce pointless nondeterminism like this?

      No - of course not.

      Comment

      • James Kanze

        #18
        Re: Template technicality - What does the standard say?

        On Oct 15, 7:03 am, Stephen Horne <sh006d3...@blu eyonder.co.ukwr ote:
        On Wed, 15 Oct 2008 16:30:54 +1300, Ian Collins
        <ian-n...@hotmail.co mwrote:
        Stephen Horne wrote:
        On Tue, 14 Oct 2008 15:58:15 -0700 (PDT), James Kanze
        <james.ka...@gm ail.comwrote:
        >Sorry, but when virtual inheritance is involved, it's
        >dynamically defined. At least with all of the compilers I
        >know, and I don't think it's possible to implement it
        >otherwise.
        I'm sorry, but it's basic textbook. The compiler determines
        what is inherited and places each inherited class at a
        particualar offset within the derived class, as if it were
        member data (which it is).
        This isn't true. See 9.2.12 and 10.0.5.
        The standard has already been quoted at me, but read James'
        point that I was replying too - this isn't about the standard,
        it's about all the compilers he knows and what he thinks is
        possible.
        I challenge you. First, define a class using *ANY* standard
        C++ features you please - multiple inheritance and virtual
        inheritance included. Lets call this class TEST.
        Now, create two instances of TEST. Don't care where you
        instantiate so long as you aren't using any further
        inheritance - global, local, normal member, static member,
        anything.
        You've suddenly introduced some new, unrealistic constraints.
        Placement new it if you think that'll make a difference. Just
        make sure you don't instance any derived classes - both must
        be instances of the exact same class, ie TEST.
        Now, show me a compiler - *ANY* compiler - that uses different
        memory layouts for those two instances.
        Basic science. The easiest way to prove that instances of a
        single class can be arranged differently in different cases is
        to provide an example, and I'm only asking for one.
        I gave one in another posting. You've just said above (for the
        first time) that you're not interested in that case. So
        offsetof can be made to work, except when it can't.

        The standard can't be based on such things. If the standard
        says it works, then it has to work.
        You won't find one. The layout of the class isn't dynamic.
        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.
        It may not be the same as the layout of any classes that
        inherit from it, but that's beside the point. Even multiple
        inheritance would break offsets if you're looking at derived
        classes.
        Not really. Given a class D, which derives virtually from a
        class B, the offsets of elements inherited from B depends on how
        D is being used---practically, it depends on which constructor
        is called (in g++'s implementation) , or which hidden argument is
        passed to the constructor (in some other implementations I've
        used).
        Can you imagine what it would be like if one instance of a
        class was arranged differently to another instance of that
        exact same class?
        I can not only imagine it, I've experienced it.
        Can you imagine any vaguely coherent reason why a
        compiler-writer would choose to introduce pointless
        nondeterminism like this?
        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.

        --
        James Kanze (GABI Software) email:james.kan ze@gmail.com
        Conseils en informatique orientée objet/
        Beratung in objektorientier ter Datenverarbeitu ng
        9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

        Comment

        • James Kanze

          #19
          Re: Template technicality - What does the standard say?

          On Oct 15, 5:56 am, Stephen Horne <sh006d3...@blu eyonder.co.ukwr ote:
          On Wed, 15 Oct 2008 16:39:32 +1300, Ian Collins <ian-n...@hotmail.co m>
          wrote:
          Stephen Horne wrote:
          In my current circumstances, paying for the standard would mean not
          eating for a week,
          You can live off $18 a week, I'm impressed.
          Not quite *that* tight, but 'live' is questionable anyway.
          That's not the price I saw for the standard (or the one James
          quoted).
          I didn't quote an exact price, because I didn't remember it.
          But I do recognize that if you don't have a regular job, even
          $18 can be a lot. (On the other hand, if you know C++, regular
          jobs are pretty easy to come by, at least here in western
          Europe. Maybe not always the best jobs in the world, but they
          still beat unemployment benefits.)
          If that price is available, next problem is no credit card. I
          refuse to get one so long as I'm on benefits for obvious
          reasons.
          A constraint that means C data structure code cannot be
          adapted and wrapped in a C++ template? IIRC, one of the
          basic design principles of C++ is that people should be
          able to adapt their C libraries without a complete rewrite.
          By definition, a C data structure is a POD struct, so you can
          use offsetof.
          template<typena me T>
          struct This_May_Not_Be _POD
          {
          T Because_This_Ma y_Not_Be_POD;
          };
          That's the whole point.
          But that' not C; it's C++. And how is it relevant to offsetof?

          --
          James Kanze (GABI Software) email:james.kan ze@gmail.com
          Conseils en informatique orientée objet/
          Beratung in objektorientier ter Datenverarbeitu ng
          9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

          Comment

          • Stephen Horne

            #20
            Re: Template technicality - What does the standard say?

            On Wed, 15 Oct 2008 01:45:58 -0700 (PDT), James Kanze
            <james.kanze@gm ail.comwrote:
            >On Oct 15, 3:06 am, Stephen Horne <sh006d3...@blu eyonder.co.ukwr ote:
            >On Tue, 14 Oct 2008 15:58:15 -0700 (PDT), James Kanze
            >I'm sorry, but it's basic textbook. The compiler determines
            >what is inherited and places each inherited class at a
            >particualar offset within the derived class, as if it were
            >member data (which it is).
            >
            >You must be reading the wrong textbooks (or you don't understand
            >virtual inheritance), since it's provably impossible to do so.
            >And it's simple to try:
            struct VB
            ....
            struct M : virtual VB
            ....
            struct D : M
            {
            int d ;
            } ;
            ....
            M v1 ;
            v1.f( std::cout ) ;
            D v2 ;
            v2.f( std::cout ) ;
            return 0 ;
            }
            >
            >I get different values for the two variables with every compiler
            >I try.
            What this proves is that you didn't read my post. You haven't
            instantiated two instances of the same class - you have instantiated
            two instances of *TWO* *DIFFERENT* *CLASSES*.

            Given all your insistence on pedantic language, how can you not notice
            that point?

            The class M uses virtual inheritance, but it's not a dynamic entity in
            itself. It's not a run-time entity at all. It has one layout. It isn't
            the same layout that is used for D, even for those components that are
            inherited from M, but that's what you get for using virtual
            inheritance. As I pointed out elsewhere, even multiple inheritance
            breaks offsetof if thats what you're dealing with.

            This issue has NOTHING to do with applications which take the
            following form...

            template<typena me T>
            struct Node
            {
            T field_within_no de;
            };

            ....

            x = offsetof (Node<M>, field_within_no de);

            Unless you're stupid enough to think the offset also applies to
            instances of Node<Dwhich is a DIFFERENT TYPE, just as D is a
            DIFFERENT TYPE to M.
            >Except that I can prove my statements. Both by example and by
            >formal proof.
            But primarily by failing to read before you reply and obsessing on an
            irrelevant issue, which invalidates both so-called proofs.

            If you can't read what I post before replying (or is it that you can't
            admit to a mistake?), I see no point in reading on.

            Comment

            • Stephen Horne

              #21
              Re: Template technicality - What does the standard say?

              On Wed, 15 Oct 2008 01:54:32 -0700 (PDT), James Kanze
              <james.kanze@gm ail.comwrote:
              >On Oct 15, 7:03 am, Stephen Horne <sh006d3...@blu eyonder.co.ukwr ote:
              >On Wed, 15 Oct 2008 16:30:54 +1300, Ian Collins
              ><ian-n...@hotmail.co mwrote:
              >Now, create two instances of TEST. Don't care where you
              >instantiate so long as you aren't using any further
              >inheritance - global, local, normal member, static member,
              >anything.
              >
              >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.
              >
              >You won't find one. The layout of the class isn't dynamic.
              >
              >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.
              >Can you imagine any vaguely coherent reason why a
              >compiler-writer would choose to introduce pointless
              >nondetermini sm like this?
              >
              >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_m ap 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*

              Comment

              • Stephen Horne

                #22
                Re: Template technicality - What does the standard say?

                On Wed, 15 Oct 2008 01:59:58 -0700 (PDT), James Kanze
                <james.kanze@gm ail.comwrote:
                >On Oct 15, 5:56 am, Stephen Horne <sh006d3...@blu eyonder.co.ukwr ote:
                >On Wed, 15 Oct 2008 16:39:32 +1300, Ian Collins <ian-n...@hotmail.co m>
                >wrote:
                >
                >Stephen Horne wrote:
                >
                >In my current circumstances, paying for the standard would mean not
                >eating for a week,
                >
                >You can live off $18 a week, I'm impressed.
                >
                >Not quite *that* tight, but 'live' is questionable anyway.
                >That's not the price I saw for the standard (or the one James
                >quoted).
                >
                >I didn't quote an exact price, because I didn't remember it.
                >But I do recognize that if you don't have a regular job, even
                >$18 can be a lot. (On the other hand, if you know C++, regular
                >jobs are pretty easy to come by, at least here in western
                >Europe. Maybe not always the best jobs in the world, but they
                >still beat unemployment benefits.)
                That's good - when you can cope with employment. It doesn't help much
                when you have a disability that means simply seeing someones face can
                trigger an autonomic stress response, simply hearing someones voice
                can trigger a stress response, and so on. It doesn't help when that
                stress response persists for certainly hours, potentially days, making
                any regular sleep and waking pattern impossible.

                Aspergers is a disability. Despite what some people think, it doesn't
                mean I just don't like people much and don't get invited to parties.
                It is a neurologically based disorder with consequences that might
                seem trivial in the short term, but the long term repercussions of all
                the stress include further brain damage that further deregulates the
                stress response and so on.

                In short, the Disney attitude dont-give-up-hope crap may be
                well-intentioned, but it can still amount to abuse, pushing people
                into situations where they end up even more disabled due to the damage
                caused by sustained stress.


                BTW - I'm not offended by what you said - no reason you should know
                this stuff - even most autistics don't know this stuff, and I'm
                starting to suspect the experts don't want to know because it would
                upset parents, teachers, etc. Anyway, it's my problem, not yours -
                just telling it as it is.


                What I *want* to do is develop my own projects on my own schedule at
                home, self employed. Not working out that way, partly because I can't
                see how to make it work. Programming? yes. Target a complete
                application to a potential market? Harder - my interests tend toward
                internals - but if I have to. But the whole business? - really can't
                see that working at all.

                I mean, can you imagine my support e-mails? ;-)

                Also, then there's the whole
                benefits-cancelled-then-the-business-goes-tits-up thing. It took the
                best part of a year to get through that crap last time around. It's
                not easy when you're too sick to go through the process that proves
                that you're sick - but only in phases so they don't really see it.

                >template<typen ame T>
                >struct This_May_Not_Be _POD
                >{
                > T Because_This_Ma y_Not_Be_POD;
                >};
                >
                >That's the whole point.
                >
                >But that' not C; it's C++. And how is it relevant to offsetof?
                It is very relevant when you take the offset of the field
                Because_This_Ma y_Not_Be_POD - remembering that this is a simplified
                illustrative example.

                Boost has code that uses offsetof, including a container that does
                exactly this - except that its This_May_Not_Be _POD struct is actually
                std::pair.


                BTW - The *PLONK* stands, as soon as I set the filter up. After all,
                we're both probably better off.

                Comment

                • Martin Eisenberg

                  #23
                  Re: Template technicality - What does the standard say?

                  Stephen Horne wrote:
                  That's good - when you can cope with employment. It doesn't help
                  much when you have a disability that means simply seeing
                  someones face can trigger an autonomic stress response, simply
                  hearing someones voice can trigger a stress response, and so on.
                  It doesn't help when that stress response persists for certainly
                  hours, potentially days, making any regular sleep and waking
                  pattern impossible.
                  Do you practice a stress-control technique? Autogenic Training and
                  various kinds of meditation can quite effectively help tame
                  the autonomic response. And don't think they're only of use to
                  neurotypicals.

                  Anyway, there's a software house in Sweden that specifically seeks
                  ADS sufferers and accomodates them with remote working etc. I can't
                  manage to seek them out now but I'll ask my source again. Or perhaps
                  someone else knows who I mean.


                  Martin

                  --
                  Sufficiently encapsulated magic is
                  indistinguishab le from technology.

                  Comment

                  • James Kanze

                    #24
                    Re: Template technicality - What does the standard say?

                    On Oct 15, 1:33 pm, Stephen Horne <sh006d3...@blu eyonder.co.ukwr ote:
                    On Wed, 15 Oct 2008 01:54:32 -0700 (PDT), James Kanze
                    <james.ka...@gm ail.comwrote:
                    On Oct 15, 7:03 am, Stephen Horne <sh006d3...@blu eyonder.co.ukwr ote:
                    On Wed, 15 Oct 2008 16:30:54 +1300, Ian Collins
                    <ian-n...@hotmail.co mwrote:
                    Now, create two instances of TEST. Don't care where you
                    instantiate so long as you aren't using any further
                    inheritance - global, local, normal member, static member,
                    anything.
                    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.
                    Who cares about what your container library might do? A
                    container library has no need of offsetof. We're talking about
                    why offsetof is not defined and not implementable in the general
                    case. And in the general case, you have to handle base classes
                    correctly.
                    These are the exact constraints I described from the start.
                    You never described any real constraints. The fact remains that
                    they are artificial constraints.
                    The standard can't be based on such things.  If the standard
                    says it works, then it has to work.
                    You won't find one. The layout of the class isn't dynamic.
                    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.
                    But the existance of a class M doesn't mean that class D ceases
                    to exist. And either offsetof( D, x ) returns a correct result,
                    constant and for all instances of D, or it can't be supported.
                    The layout for either one is fixed.
                    The layout of M isn't fixed. It varies depending on how M is
                    used.
                    As for not considering your irrelevant contexts, what the hell
                    do you expect. Inheritance has nothing to do with offsetof.
                    Agreed. The committee didn't want to open up that hornets'
                    nest, so they restricted offsetof to PODS. And a PODS cannot
                    inherit, much less virtually.
                    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?
                    Because they're real issues, and it's necessary to address them
                    if you want to support offsetof for non-PODS.
                    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.
                    And a class which derives from another class virtually doesn't
                    have a fixed layout.
                    Can you imagine any vaguely coherent reason why a
                    compiler-writer would choose to introduce pointless
                    nondeterminism like this?
                    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.
                    Exactly. We're talking about a field in M. Whose position
                    changes depending on how you use M.
                    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.
                    Which is why it is restricted to PODS, which do have constant
                    offsets, known to the compiler.

                    [...]
                    But even for that, lets face it - most people would call
                    virtual inheritance a niche tool at best,
                    It's widely used, and vitally necessary for many things.


                    --
                    James Kanze (GABI Software) email:james.kan ze@gmail.com
                    Conseils en informatique orientée objet/
                    Beratung in objektorientier ter Datenverarbeitu ng
                    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                    Comment

                    • James Kanze

                      #25
                      Re: Template technicality - What does the standard say?

                      On Oct 15, 11:26 am, Stephen Horne <sh006d3...@blu eyonder.co.uk>
                      wrote:
                      On Wed, 15 Oct 2008 01:45:58 -0700 (PDT), James Kanze
                      <james.ka...@gm ail.comwrote:
                      On Oct 15, 3:06 am, Stephen Horne <sh006d3...@blu eyonder.co.ukwr ote:
                      On Tue, 14 Oct 2008 15:58:15 -0700 (PDT), James Kanze I'm
                      sorry, but it's basic textbook. The compiler determines
                      what is inherited and places each inherited class at a
                      particualar offset within the derived class, as if it were
                      member data (which it is).
                      You must be reading the wrong textbooks (or you don't
                      understand virtual inheritance), since it's provably
                      impossible to do so. And it's simple to try:
                         struct VB
                      ...
                         struct M : virtual VB
                      ...
                         struct D : M
                         {
                             int                 d ;
                         } ;
                      ...
                             M                   v1 ;
                             v1.f( std::cout ) ;
                             D                   v2 ;
                             v2.f( std::cout ) ;
                             return 0 ;
                         }
                      I get different values for the two variables with every
                      compiler I try.
                      What this proves is that you didn't read my post.
                      What this proves is what I said it proves. That sizeof is not
                      implementable for certain types.
                      You haven't instantiated two instances of the same class - you
                      have instantiated two instances of *TWO* *DIFFERENT*
                      *CLASSES*.
                      Do you know any C++ at all? I've definitly got two instances of
                      M; one in one context, and one that isn't.
                      Given all your insistence on pedantic language, how can you
                      not notice that point?
                      Did you notice that there is an M object in the D? Do you
                      understand what is meant by a type?
                      The class M uses virtual inheritance, but it's not a dynamic
                      entity in itself. It's not a run-time entity at all. It has
                      one layout.
                      Which is? It quite obviously has two different layouts in my
                      code above, depending on whether it is a base class of D or not.
                      It isn't the same layout that is used for D, even for those
                      components that are inherited from M, but that's what you get
                      for using virtual inheritance. As I pointed out elsewhere,
                      even multiple inheritance breaks offsetof if thats what you're
                      dealing with.
                      Not at this level. Modulo access issues and possible
                      ambiguities, offsetof could be well defined for multiple
                      inheritance, as long as no virtual inheritance is involved.
                      This issue has NOTHING to do with applications which take the
                      following form...
                      Whether offsetof is implementable for non PODS has nothing to do
                      with any application. It's a matter of principle: either the
                      offset is fixed, or it's not. In the case of C++, it's not, at
                      least when virtual inheritance is involved.
                      Unless you're stupid enough to think the offset also applies
                      to instances of Node<Dwhich is a DIFFERENT TYPE, just as D
                      is a DIFFERENT TYPE to M.
                      Except that I can prove my statements.  Both by example and
                      by formal proof.
                      But primarily by failing to read before you reply and
                      obsessing on an irrelevant issue, which invalidates both
                      so-called proofs.
                      If you can't read what I post before replying (or is it that
                      you can't admit to a mistake?), I see no point in reading on.
                      In other words, you've lost the argument, so you're taking your
                      ball and going home.

                      I'd suggest you actually learn C++ before trying to criticize
                      it.

                      --
                      James Kanze (GABI Software) email:james.kan ze@gmail.com
                      Conseils en informatique orientée objet/
                      Beratung in objektorientier ter Datenverarbeitu ng
                      9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                      Comment

                      • James Kanze

                        #26
                        Re: Template technicality - What does the standard say?

                        On Oct 15, 2:25 pm, Stephen Horne <sh006d3...@blu eyonder.co.ukwr ote:
                        On Wed, 15 Oct 2008 01:59:58 -0700 (PDT), James Kanze
                        <james.ka...@gm ail.comwrote:
                        On Oct 15, 5:56 am, Stephen Horne <sh006d3...@blu eyonder.co.ukwr ote:
                        On Wed, 15 Oct 2008 16:39:32 +1300, Ian Collins
                        <ian-n...@hotmail.co mwrote:
                        Stephen Horne wrote:
                        In my current circumstances, paying for the standard
                        would mean not eating for a week,
                        You can live off $18 a week, I'm impressed.
                        Not quite *that* tight, but 'live' is questionable anyway.
                        That's not the price I saw for the standard (or the one
                        James quoted).
                        I didn't quote an exact price, because I didn't remember it.
                        But I do recognize that if you don't have a regular job, even
                        $18 can be a lot.  (On the other hand, if you know C++,
                        regular jobs are pretty easy to come by, at least here in
                        western Europe.  Maybe not always the best jobs in the world,
                        but they still beat unemployment benefits.)
                        That's good - when you can cope with employment. It doesn't
                        help much when you have a disability that means simply seeing
                        someones face can trigger an autonomic stress response, simply
                        hearing someones voice can trigger a stress response, and so
                        on. It doesn't help when that stress response persists for
                        certainly hours, potentially days, making any regular sleep
                        and waking pattern impossible.
                        That's a serious disability, and if it is really that bad, it
                        pretty much means that you need to consider a different
                        profession. Programming is a team activity; you can't develop
                        good programs without working with others, and communicating
                        with them. Face to face and in writing.
                        Aspergers is a disability.
                        I won't argue with that. Although I'm not familiar with this
                        particular disability. There are lots of different types of
                        disabilities, and some of the disqualify the person for some
                        particular types of employ---you don't see many blind taxi
                        drivers, for example, and that's not because of anything I'd
                        consider discrimination against the blind. If you're going to
                        work in programming, not being able to meet and discuss things
                        with your collegues is a disqualifying disability, whatever its
                        reasons may be.

                        [...]
                        In short, the Disney attitude dont-give-up-hope crap may be
                        well-intentioned, but it can still amount to abuse, pushing
                        people into situations where they end up even more disabled
                        due to the damage caused by sustained stress.
                        Well, I suspect that there are some cases where you do have to
                        give up hope. I once had a blind friend who wanted to be a race
                        car driver. Realistically.. .

                        There are, of course, a lot of other things one can do.
                        BTW - I'm not offended by what you said - no reason you should
                        know this stuff - even most autistics don't know this stuff,
                        and I'm starting to suspect the experts don't want to know
                        because it would upset parents, teachers, etc. Anyway, it's my
                        problem, not yours - just telling it as it is.
                        What I *want* to do is develop my own projects on my own
                        schedule at home, self employed. Not working out that way,
                        partly because I can't see how to make it work. Programming?
                        yes. Target a complete application to a potential market?
                        Harder - my interests tend toward internals - but if I have
                        to. But the whole business? - really can't see that working at
                        all.
                        I mean, can you imagine my support e-mails? ;-)
                        All of us have our limits; maybe not as serious as yours, but I
                        tend to avoid support work as well; it doesn't fit me.
                        template<typena me T>
                        struct This_May_Not_Be _POD
                        {
                          T  Because_This_Ma y_Not_Be_POD;
                        };
                        That's the whole point.
                        >
                        But that' not C; it's C++.  And how is it relevant to offsetof?
                        It is very relevant when you take the offset of the field
                        Because_This_Ma y_Not_Be_POD - remembering that this is a
                        simplified illustrative example.
                        But the purpose of having offsetof in C++ is only backwards
                        compatibility with C. For all of the known uses of offsetof to
                        me, C++ has better alternatives.

                        --
                        James Kanze (GABI Software) email:james.kan ze@gmail.com
                        Conseils en informatique orientée objet/
                        Beratung in objektorientier ter Datenverarbeitu ng
                        9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                        Comment

                        • Paavo Helde

                          #27
                          Re: Template technicality - What does the standard say?

                          Stephen Horne <sh006d3592@blu eyonder.co.ukki rjutas:
                          >
                          This from the guy who just declared that offsetof is only there for C
                          compatibility, and shouldn't be used.
                          >
                          OK - what's the alternative, then?
                          As Stephen is not so prone to provide compilable code samples, I will
                          provide one of my own distilled from working production code. I have no
                          idea if it bears any resemblance to Stephen's issues, but I think this is
                          something which could make use of a generalized offsetof() macro. What
                          the code does is to register the offset of a variable ("parameter" ) in a
                          derived class in another dynamic library, and assigning it a value later.

                          Restrictions:

                          Derived class must be as simple as possible (there are hundreds of such
                          classes). When started, Derived::Run() should just find the class member
                          parameters initialized to needed values.

                          In this example only one parameter of type 'int' is used. In reality
                          there are arbitrarily many parameters of multiple (restricted set of)
                          possible types. The parameter registration involves communicating both
                          the parameter type and offset, the type (an enum value) omitted here for
                          brevity. So the parameters cannot be just passed as parameters for the
                          Run() function.

                          The Base class and main() do not know anything about the Derived class.

                          Task:

                          The ob1 object in line A is actually not used except for finding out the
                          offsets of parameter data members. Please rewrite the code so that
                          creation of this dummy object ob1 would not be needed.

                          The code follows:

                          // MAIN EXECUTABLE
                          #include <iostream>

                          class Base {
                          public:
                          Base(): base_data_(111) {}
                          virtual int Declare()=0;
                          virtual void Run()=0;
                          virtual ~Base(){}
                          protected:
                          int RegisterInput(v oid* memberaddr) {
                          return static_cast<cha r*>(memberaddr)
                          - static_cast<cha r*>(static_cast <void*>(this) );
                          }
                          private:
                          int base_data_;
                          };

                          typedef Base* (*creator_funct ype)();
                          creator_functyp e RegisterDerived ();

                          int main() {
                          creator_functyp e creator = RegisterDerived ();

                          // Find out the offset of param1_ in the Derived class.
                          Base* ob1 = (*creator)(); //LINE A
                          int offset = ob1->Declare();
                          delete ob1;

                          // Much later, and many times: assign value to param1_ and call Run.
                          Base* ob2 = (*creator)();
                          *static_cast<in t*>(static_cast <void*>
                          (static_cast<ch ar*>(static_cas t<void*>(ob2))+ offset)) = 42;
                          ob2->Run();
                          delete ob2;
                          }

                          // MIGHT BE IN A SEPARATE LIBRARY
                          class Derived: public Base {
                          public:
                          virtual int Declare() {
                          return RegisterInput(& param1_);
                          }
                          virtual void Run() {
                          std::cout << "param1=" << param1_ << "\n";
                          }
                          static Base* Create() {return new Derived();}
                          private:
                          int param1_;
                          };
                          creator_functyp e RegisterDerived () {return &Derived::Creat e;}

                          Comment

                          • Stephen Horne

                            #28
                            Re: Template technicality - What does the standard say?

                            On 15 Oct 2008 13:57:07 GMT, Martin Eisenberg
                            <martin.eisenbe rg@udo.eduwrote :
                            >Stephen Horne wrote:
                            >
                            >That's good - when you can cope with employment. It doesn't help
                            >much when you have a disability that means simply seeing
                            >someones face can trigger an autonomic stress response, simply
                            >hearing someones voice can trigger a stress response, and so on.
                            >It doesn't help when that stress response persists for certainly
                            >hours, potentially days, making any regular sleep and waking
                            >pattern impossible.
                            >
                            >Do you practice a stress-control technique? Autogenic Training and
                            >various kinds of meditation can quite effectively help tame
                            >the autonomic response. And don't think they're only of use to
                            >neurotypical s.
                            Those techniques depend on the link back from the prefrontal cortex to
                            the amygdala being intact - the link that switches off unnecessary
                            stress reactions. It's a fragile link. Both the amygdala and the
                            prefrontal cortex are known damaged in autistic spectrum disorders.

                            In principle, aromatherapy is about the most likely option to work.
                            The senses of smell and taste are processed directly in the amygdala,
                            which is the main autonomic stress response trigger. There's no
                            guarantee, though, that any smell would make any difference and all I
                            can say for certain is that I like citrus smells.

                            The point is that stress control techniques only work if I'm not
                            really all that stressed anyway. Bear in mind that my really good day
                            is probably comparable to a normal persons really bad day.

                            I obsessed with trying to fix myself for decades before finding out
                            what the problem is. I've tried plenty. What seemed to work in a sense
                            basically turned out to be a flavor of cognitive behavioural therapy,
                            but all it was really doing was training me to take on more and more
                            stress.

                            The stress response isn't all negative emotions. Think adrenaline
                            junkie thrills, excitement and mania. Irrespective of whether it feels
                            good or bad, your brain and body are still running beyond their
                            sustainable limits and they are still damaging themselves further, and
                            you are still going to crash and burn. And the next burnout will be
                            faster and more severe, and so on.
                            >Anyway, there's a software house in Sweden that specifically seeks
                            >ADS sufferers and accomodates them with remote working etc. I can't
                            >manage to seek them out now but I'll ask my source again. Or perhaps
                            >someone else knows who I mean.
                            Wouldn't they want people who can speak Swedish?

                            Comment

                            • Stephen Horne

                              #29
                              Re: Template technicality - What does the standard say?

                              On Wed, 15 Oct 2008 17:33:04 -0500, Paavo Helde <nobody@ebi.eew rote:
                              >Stephen Horne <sh006d3592@blu eyonder.co.ukki rjutas:
                              >
                              >>
                              >This from the guy who just declared that offsetof is only there for C
                              >compatibilit y, and shouldn't be used.
                              >>
                              >OK - what's the alternative, then?
                              >
                              >As Stephen is not so prone to provide compilable code samples
                              The following compilable code sample has been provided many times...

                              template<class T>
                              struct whatever
                              {
                              T field;
                              };

                              ....

                              x = offsetof(whatev er, field);

                              For full compilable source, we're talking 7 separate source files with
                              sizes ranging from about 1000 to about 2500 lines each. Therefore,
                              descriptions and simplified examples.

                              I have also provided a reference to a Boost source file that does
                              basically what I do. Go to www.koders.com and you'll find other
                              examples. It's not everyday stuff, any more than member pointers or
                              virtual inheritance, but it's used.


                              Single inheritance as in your example won't break offsetof in
                              practice, but IMO it's not the right solution for this.

                              If any Derived uses Multiple inheritance or virtual inheritance, even
                              indirectly, offsetof definitely breaks. On some compilers, having
                              virtual inheritance will cause offsetof to crash immediately (or at
                              least generate nonsense), since the traditional macro expansion would
                              end up trying to read the virtual table of a non-existent instance.

                              OTOH, if Derived is no worse than single inheritance, having fields
                              that have multiple-inheritance or virtual-inheritance types won't
                              break it - in practice only - no guarantees from the standard since
                              your classes are non-POD (even without the inheritance issues from
                              above).

                              However, because this depends on users following a rule that the
                              compiler won't enforce for you, its unsafe. My experience is that
                              people will forget about that rule.

                              I'll assume you have good reasons for not making param1 a parameter of
                              Run.

                              I'd recommend using pure access functions declared in Base to get at
                              param1. The virtual call overhead *might* be a problem for you, but
                              don't optimise until you're sure you need to.

                              Even if you need to optimise, there are much safer ways to do it. e.g.
                              You could provide an pure access function in Base that returns a
                              reference or pointer to the variable within the instance. Then you can
                              update the buffer as often as you like with minimal cost, so long as
                              the instance stays put. If there's any possibility that the user might
                              put the buffer somewhere outside the instance, a lock-and-release
                              approach might be worthwhile to at least make it explicit that the
                              buffer is meant to stay put and for how long.

                              That gives you something like...

                              BUFFER buffer = obj->lock_buffer ();
                              // I'll assume exception-for-fail - why nullcheck when most
                              // implementations will be trivial and infallible.

                              while (...)
                              {
                              *buffer = whatever;
                              obj->Run ();
                              }

                              obj->release_buff er (buffer);

                              Even if you use a member pointer, the basic principle of converting to
                              a simple pointer before entering an inner loop still makes sense - and
                              one advantage if member pointers work for you is that the compiler
                              will probably do that optimisation for you.

                              But access functions are the basic workhorse for doing this kind of
                              thing - member pointers cause too many problems to be practical in my
                              experience, and offsetof is unsafe if the type of the instance is a
                              run-time variable.

                              Comment

                              • James Kanze

                                #30
                                Re: Template technicality - What does the standard say?

                                On Oct 16, 12:33 am, Paavo Helde <nob...@ebi.eew rote:
                                Stephen Horne <sh006d3...@blu eyonder.co.ukki rjutas:
                                This from the guy who just declared that offsetof is only
                                there for C compatibility, and shouldn't be used.
                                OK - what's the alternative, then?
                                As Stephen is not so prone to provide compilable code samples,
                                Stephen seems mainly prone to insulting the committee because
                                they didn't design the language exactly according to his
                                desires.

                                The problem is simple: C++ inherited offsetof from C. When
                                <cstddefwas being defined, the problem of defining what
                                offsetof meant in C++ (with class types, rather than struct
                                types) had to be addressed. The simplest solution (in terms of
                                actual work) was just to limit it to what is basically C: PODS.
                                Obviously, other solutions are possible, but some restrictions
                                are necessary. Clearly defining those restrictions is
                                additional work. Apparently, no one at the time felt it worth
                                the effort---either they didn't see any important use of
                                offsetof, or they felt that there were more important things to
                                do, or whatever. The committee depends on volontary effort, and
                                no one volonteered to extend offsetof to non-POD types.

                                All of the rest is really just useless discussion. I don't
                                particularly see much use of offsetof, and I've written a lot of
                                low level code. Which explains why I didn't volonteer to do the
                                work of extending it. The fact that many others working in the
                                committee apparently felt like me is the real reason why
                                offsetof isn't defined for non PODS. (The fact that many others
                                working in the committee -- most of whom are considerably more
                                competent than I am -- apparently felt like me reassures me.
                                All too often, I'm in disagreement with a large part of the
                                committee, which makes me wonder.)

                                --
                                James Kanze (GABI Software) email:james.kan ze@gmail.com
                                Conseils en informatique orientée objet/
                                Beratung in objektorientier ter Datenverarbeitu ng
                                9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                                Comment

                                Working...