this used in initialiser

Discussion in 'C++' started by Fraser Ross, Jun 25, 2009.

  1. Fraser Ross

    Fraser Ross Guest

    class base {
    public:
    base(void *) {}
    };

    class der : base {
    public:
    der() :base(this) {}
    };

    Does this have any defined value when used in a base class initialiser?
    Only 1 out of 3 compilers have given a warning.

    Fraser.
     
    Fraser Ross, Jun 25, 2009
    #1
    1. Advertising

  2. Fraser Ross

    Fraser Ross Guest

    I think it points to an uninitialised sub-object. It needs to be used
    with some care.

    Fraser.
     
    Fraser Ross, Jun 25, 2009
    #2
    1. Advertising

  3. Fraser Ross wrote:
    > class base {
    > public:
    > base(void *) {}
    > };
    >
    > class der : base {
    > public:
    > der() :base(this) {}
    > };
    >
    > Does this have any defined value when used in a base class initialiser?


    Absolutely.

    It points to the memory where the respective object resides (or will
    reside once initialised).

    > Only 1 out of 3 compilers have given a warning.


    You are not prohibited from using 'this' in the initialiser list. Just
    be careful, the object hasn't been fully initialised yet.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Jun 25, 2009
    #3
  4. Fraser Ross

    James Kanze Guest

    On Jun 25, 7:25 pm, "Fraser Ross" <> wrote:
    > class base {
    > public:
    > base(void *) {}
    > };


    > class der : base {
    > public:
    > der() :base(this) {}
    > };


    > Does this have any defined value when used in a base class
    > initialiser?


    Yes, but it might not be what is wanted. The implicit
    conversion to void* is very dangerous here; not only can base
    not use the pointer in its constructor, it must convert it to
    der* in order to use it later.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jun 26, 2009
    #4
  5. Fraser Ross

    James Kanze Guest

    On Jun 25, 9:29 pm, Victor Bazarov <> wrote:
    > Fraser Ross wrote:
    > > class base {
    > > public:
    > > base(void *) {}
    > > };


    > > class der : base {
    > > public:
    > > der() :base(this) {}
    > > };


    > > Does this have any defined value when used in a base class
    > > initialiser?


    > Absolutely.


    > It points to the memory where the respective object resides
    > (or will reside once initialised).


    It points to the memory where the der object will reside. The
    only way the base class can correctly use it is by reconverting
    it to a der*.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jun 26, 2009
    #5
  6. Fraser Ross

    Fraser Ross Guest


    >"James Kanze"
    >On Jun 25, 7:25 pm, "Fraser Ross"
    >> class base {
    >> public:
    >> base(void *) {}
    >> };


    >> class der : base {
    >> public:
    >> der() :base(this) {}
    >> };


    >> Does this have any defined value when used in a base class
    >> initialiser?


    >Yes, but it might not be what is wanted. The implicit
    >conversion to void* is very dangerous here; not only can base
    >not use the pointer in its constructor, it must convert it to
    >der* in order to use it later.



    It could also be converted later to base*.

    I think my real code might violate 12.7/3. Where it says "might use
    path E* -> D*-> A*" is it implying that conversions from E* to C* and D*
    are equally good because they are directly inherited base classes? If I
    remove C, B and X from the example and force the conversions of E* ->
    D*-> A* the Comeau compiler gives no diagnostics but the standard is
    saying its undefined behaviour.

    struct A { };

    struct D : virtual A {
    D(A*);
    };

    struct E : D {
    E() : D(this) {}// undefined: upcast from E* to A* might use path E* !
    D* ! A*
    };

    Fraser.
     
    Fraser Ross, Jun 26, 2009
    #6
  7. Fraser Ross

    James Kanze Guest

    On Jun 26, 2:20 pm, "Fraser Ross" <> wrote:
    > >"James Kanze"
    > >On Jun 25, 7:25 pm, "Fraser Ross"
    > >> class base {
    > >> public:
    > >> base(void *) {}
    > >> };
    > >> class der : base {
    > >> public:
    > >> der() :base(this) {}
    > >> };
    > >> Does this have any defined value when used in a base class
    > >> initialiser?

    > >Yes, but it might not be what is wanted. The implicit
    > >conversion to void* is very dangerous here; not only can base
    > >not use the pointer in its constructor, it must convert it to
    > >der* in order to use it later.


    > It could also be converted later to base*.


    If you don't mind undefined behavior. The only legal use of a
    void* is converting it back to the original type. Here, the
    original type is der*, not base*.

    > I think my real code might violate 12.7/3. Where it says
    > "might use path E* -> D*-> A*" is it implying that conversions
    > from E* to C* and D* are equally good because they are
    > directly inherited base classes? If I remove C, B and X from
    > the example and force the conversions of E* -> D*-> A* the
    > Comeau compiler gives no diagnostics but the standard is
    > saying its undefined behaviour.


    You'll have to show use your real code. My comments concerning
    undefined behavior mainly concerned the passage through a void*.
    The examples in 12.7/3 don't have any void*. §12.7/2 does
    guarantee that you could pass your this to a base*, but it
    doesn't say anything about a void*.

    > struct A { };


    > struct D : virtual A {
    > D(A*);
    > };


    > struct E : D {
    > E() : D(this) {}// undefined: upcast from E* to A* might use path E* !
    > D* ! A*
    > };


    I'm not sure vis-a-vis the standard, but I do know that this
    fails with certain compilers.

    Curiously, you can call member functions of A in the same
    context (and calling such functions requires the same
    conversion). And the member function can return its this
    pointer.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jun 26, 2009
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. John Harrison
    Replies:
    2
    Views:
    1,277
    =?iso-8859-1?Q?Juli=E1n?= Albo
    Jun 25, 2003
  2. Martin Zimmermann
    Replies:
    2
    Views:
    504
    Rob Williscroft
    Apr 14, 2004
  3. Mike Hewson
    Replies:
    14
    Views:
    11,921
    Micah Cowan
    Jan 7, 2005
  4. Glen Able

    Reference + initialiser oddity.

    Glen Able, Jan 28, 2005, in forum: C++
    Replies:
    3
    Views:
    373
    Ioannis Vranos
    Jan 29, 2005
  5. Colon initialiser?

    , Jan 24, 2007, in forum: C Programming
    Replies:
    11
    Views:
    588
    Stephen Sprunk
    Jan 25, 2007
Loading...

Share This Page