this used in initialiser

F

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?
Only 1 out of 3 compilers have given a warning.

Fraser.
 
F

Fraser Ross

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

Fraser.
 
V

Victor Bazarov

Fraser said:
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
 
J

James Kanze

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

James Kanze

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

Fraser Ross

"James Kanze"
On Jun 25, 7:25 pm, "Fraser Ross"
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.
 
J

James Kanze

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top