C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Dynamic cast offsets without an instance

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Jacek Generowicz
Guest





PostPosted: Sat Apr 24, 2004 12:04 am    Post subject: Dynamic cast offsets without an instance Reply with quote



Brief summary of question:

Is it possible to calculate by how much a dynamic_cast adjusts a
pointer, without having an instance of the class(es) involved in the
cast ?

----------------------------------------------------------------------

More details:

Please consider the following code

#include <iostream>

struct Base {
int datum;
virtual ~Base(){}
};

struct Derived : public virtual Base {};

int main() {

Base* b = new Derived;
Derived* d = dynamic_cast<Derived*>(b);
std::cout << (int)d - (int)b << std::endl;

return 0;
}

Output on gcc:

-4

Is there a way of persuading C++ compilers to calculate the quantity
which was calculated above, without having an instance of Derived (or
of Base) ?

(Note, there are 3 different tyes involved here, in general:

- static source type (SST)

- static destination type (SDT)

- dynamic type (DyT)

The last, could, in general be different from both of the previous
two; an instance of a class derived from Derived.)

---------------------------------------------------------------------

Background and motivation:

I am using some code which attempts to add some sort of introspection
to C++ (based on GCC_XML) and which allows interaction with C++
classes (and their instances) found in dynamic libraries for which the
system has constructed a "dictionary".

This system requires the aforementioned offsets in order to simulate
dynamic casting. It attempts to find them by default-constructing
instances of the classes, and performing a dynamic_cast ... but not
all classes have default constructors.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Bill Weston
Guest





PostPosted: Sun Apr 25, 2004 1:51 am    Post subject: Re: Dynamic cast offsets without an instance Reply with quote



Jacek Generowicz <jacek.generowicz (AT) cern (DOT) ch> wrote

Quote:
Brief summary of question:

Is it possible to calculate by how much a dynamic_cast adjusts a
pointer, without having an instance of the class(es) involved in the
cast ?

Sorry, don't know. Would be interested to find out if so, but expect

to be disappointed.

[snip]
Quote:
Background and motivation:

[snip]
This system requires the aforementioned offsets in order to simulate
dynamic casting. It attempts to find them by default-constructing
instances of the classes, and performing a dynamic_cast ... but not
all classes have default constructors.

As a tiny amelioration of this difficulty, you could wrap up the
default constructor as a default template, something like New<Foo>,
and specialise where there is no default ctor to whatever factory
function is necessary... something like (untested):

template<typename T>
struct New
{
T* tmp;
operator T*(){ return tmp; }
New(): tmp(new T()) {}
~New(){ delete tmp; } // depending on who is to own it
};

template<>
sctruct New<Foo>
{
// do whatever it takes!
}

Hoping someone posts a proper answer to your interesting question,
Bill Weston

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Carl Barron
Guest





PostPosted: Sun Apr 25, 2004 10:45 pm    Post subject: Re: Dynamic cast offsets without an instance Reply with quote



Jacek Generowicz <jacek.generowicz (AT) cern (DOT) ch> wrote:

Quote:
Background and motivation:

I am using some code which attempts to add some sort of introspection
to C++ (based on GCC_XML) and which allows interaction with C++
classes (and their instances) found in dynamic libraries for which the
system has constructed a "dictionary".

This system requires the aforementioned offsets in order to simulate
dynamic casting. It attempts to find them by default-constructing
instances of the classes, and performing a dynamic_cast ... but not
all classes have default constructors.
Does your compiler optimize away the added space for a struct

containing no addition data and possibly a default constructor?
Consider:
// Default setup class is default constructable so use the
// general template here:

template <class T> struct Wrapper:T{};

// for each class requiring a non default constructor are there fairly
// easy to construct areguments for this constructor?
// then template specialization like this:
struc non_default_constructor
{
non_default_constructor(int,const std::string &x);
}

template <> struct Wrapper<non_default_constructor>:T
{
Wrapper():T(0,""){}
};

// etc.

Will this work??
It is possible to use Loki to generate the code to generate the
results fairly easily using a TypeList of types derived from a base
class and that base class. [details omitted but doable if this works.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Paul D. DeRocco
Guest





PostPosted: Sun Apr 25, 2004 11:17 pm    Post subject: Re: Dynamic cast offsets without an instance Reply with quote

Quote:
"Jacek Generowicz" <jacek.generowicz (AT) cern (DOT) ch> wrote

Brief summary of question:

Is it possible to calculate by how much a dynamic_cast adjusts a
pointer, without having an instance of the class(es) involved in the
cast ?

No. Without an actual instance, you can't do anything fancier than you can
with static_cast.

--

Ciao, Paul D. DeRocco
Paul mailto:pderocco (AT) ix (DOT) netcom.com


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Michiel Salters
Guest





PostPosted: Mon Apr 26, 2004 2:23 pm    Post subject: Re: Dynamic cast offsets without an instance Reply with quote

Jacek Generowicz <jacek.generowicz (AT) cern (DOT) ch> wrote

Quote:
Brief summary of question:

Is it possible to calculate by how much a dynamic_cast adjusts a
pointer, without having an instance of the class(es) involved in the
cast ?

No:

struct A { virtual ~A() {} };
struct B : public A { };
struct C : public A { };
struct D : public B, public C { };

The adjustment from A* to D* depends on which of the two A bases
the A* points to, which in general is a runtime property.

Regards,
Michiel Salters

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Jacek Generowicz
Guest





PostPosted: Tue Apr 27, 2004 10:50 am    Post subject: Re: Dynamic cast offsets without an instance Reply with quote

[email]Michiel.Salters (AT) logicacmg (DOT) com[/email] (Michiel Salters) writes:

Quote:
Jacek Generowicz <jacek.generowicz (AT) cern (DOT) ch> wrote

Brief summary of question:

Is it possible to calculate by how much a dynamic_cast adjusts a
pointer, without having an instance of the class(es) involved in the
cast ?

No:

struct A { virtual ~A() {} };
struct B : public A { };
struct C : public A { };
struct D : public B, public C { };

The adjustment from A* to D* depends on which of the two A bases
the A* points to, which in general is a runtime property.

Indeed. I didn't really mean "compiler", I meant "compiler and
runtime" or maybe "implementation". IOW, I'm trying to avoid, if at
all possible, having to feed in implementation dependent knowledge
about the objects' layouts; I would like the implementation to give me
this information.

Perhaps a slightly different approach might work ...

Is there some run-time programmatic way to access the underlying
functionality of dynamic_cast? a means of specifying, at run-time, the
type to which the cast should be performed. If it were somehow
possible to specify the target type of the cast by passing a typeinfo
pointer[*], rather than with a template argument, this would probably be
quite satisfactory. Even if it is an implementation dependent trick,
it seems much cleaner and more manageable than implementation
dependent layout knowledge.


[*] The static source type would also have to be communicated by
typeinfo, I suppose.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
David Baraff
Guest





PostPosted: Wed Apr 28, 2004 9:34 am    Post subject: Re: Dynamic cast offsets without an instance Reply with quote

Jacek Generowicz <jacek.generowicz (AT) cern (DOT) ch> wrote in message news:
Quote:
Is there some run-time programmatic way to access the underlying
functionality of dynamic_cast? a means of specifying, at run-time, the
type to which the cast should be performed.

In g++ (certainly in 3.3, and going back for a few releases) the
functionality you want is described in the cxxabi.h header file. In
particular, the RTTI datastructures give you access to the inheritance
graph, and the offsets are also encoded. You'll probably have to read
the file a bunch of times before it makes sense, but you can
essentially say "take this void*, pretend it is of type T1, cast it to
a void* that would point to a T2." (Where you communicate T1 and T2
by passing type_info's.)

Of course, the drawback is that this technique limits you to compilers
that support this particular ABI (which is hopefully soon going to be
many compilers). For example, I wouldn't hold my breath waiting for
this to work under the Microsoft C++ compiler...

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Jacek Generowicz
Guest





PostPosted: Wed Apr 28, 2004 7:41 pm    Post subject: Re: Dynamic cast offsets without an instance Reply with quote

[email]deb (AT) pixar (DOT) com[/email] (David Baraff) writes:

Quote:
Jacek Generowicz <jacek.generowicz (AT) cern (DOT) ch> wrote in message news:
Is there some run-time programmatic way to access the underlying
functionality of dynamic_cast? a means of specifying, at run-time, the
type to which the cast should be performed.

In g++ (certainly in 3.3, and going back for a few releases) the
functionality you want is described in the cxxabi.h header file.

Yes, this seems to do the trick ... for example:

#include <iostream>
#include <cxxabi.h>

struct Base {
int datum;
virtual ~Base(){}
};

struct Derived : public virtual Base {};

int main() {

// The usual static approach
Base* b = new Derived;
Derived* d = dynamic_cast<Derived*>(b);
std::cout << (int)d - (int)b << std::endl;

// The runtime-via-typeinfo approach
void* vb = (void*) b;
__cxxabiv1::__class_type_info* Bti = (__cxxabiv1::__class_type_info*)(&typeid(Base));
__cxxabiv1::__class_type_info* Dti = (__cxxabiv1::__class_type_info*)(&typeid(Derived));
void* vd = __cxxabiv1::__dynamic_cast(vb, Bti, Dti, -1);
std::cout << (int)vd - (int)vb << std::endl;

return 0;
}

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Jacek Generowicz
Guest





PostPosted: Wed Apr 28, 2004 7:45 pm    Post subject: Re: Dynamic cast offsets without an instance Reply with quote

[email]deb (AT) pixar (DOT) com[/email] (David Baraff) writes:

Quote:
In g++ (certainly in 3.3, and going back for a few releases) the
functionality you want is described in the cxxabi.h header file.

[...]

Quote:
you can essentially say "take this void*, pretend it is of type T1,
cast it to a void* that would point to a T2." (Where you
communicate T1 and T2 by passing type_info's.)

Perfect, that's exactly the sort of thing I was thinking of. I'll dig
around in there. Thanks.

Quote:
Of course, the drawback is that this technique limits you to compilers
that support this particular ABI (which is hopefully soon going to be
many compilers). For example, I wouldn't hold my breath waiting for
this to work under the Microsoft C++ compiler...

Indeed, but if there is no more portable alternative, then so be it.

Anyone know where to look for this sort of thing in MSVC ?

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Bill Weston
Guest





PostPosted: Thu Apr 29, 2004 9:27 pm    Post subject: Re: Dynamic cast offsets without an instance Reply with quote

Jacek Generowicz <jacek.generowicz (AT) cern (DOT) ch> wrote

Quote:
deb (AT) pixar (DOT) com (David Baraff) writes:

Jacek Generowicz <jacek.generowicz (AT) cern (DOT) ch> wrote in message news:
Is there some run-time programmatic way to access the underlying
functionality of dynamic_cast? a means of specifying, at run-time, the
type to which the cast should be performed.

In g++ (certainly in 3.3, and going back for a few releases) the
functionality you want is described in the cxxabi.h header file.

Yes, this seems to do the trick ... for example:

#include <iostream
#include
struct Base {
int datum;
virtual ~Base(){}
};

struct Derived : public virtual Base {};

int main() {

// The usual static approach
Base* b = new Derived;
Derived* d = dynamic_cast std::cout << (int)d - (int)b << std::endl;

// The runtime-via-typeinfo approach
void* vb = (void*) b;
__cxxabiv1::__class_type_info* Bti = (__cxxabiv1::__class_type_info*)(&typeid(Base));
__cxxabiv1::__class_type_info* Dti = (__cxxabiv1::__class_type_info*)(&typeid(Derived));
void* vd = __cxxabiv1::__dynamic_cast(vb, Bti, Dti, -1);
std::cout << (int)vd - (int)vb << std::endl;

return 0;
}


THis is cool! It makes multiple dispatch possible naturally within
the laguage, albeit with explicit registration of dispatchees.

Hmmmm. Multiply dispatching observer patterns maybe, since one needs
to register observers anyway.


Cheers,
Bill Weston

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Jacek Generowicz
Guest





PostPosted: Fri Apr 30, 2004 11:20 am    Post subject: Re: Dynamic cast offsets without an instance Reply with quote

Jacek Generowicz <jacek.generowicz (AT) cern (DOT) ch> writes:

Quote:
__cxxabiv1::__class_type_info* Bti = (__cxxabiv1::__class_type_info*)(&typeid(Base));
__cxxabiv1::__class_type_info* Dti = (__cxxabiv1::__class_type_info*)(&typeid(Derived));
void* vd = __cxxabiv1::__dynamic_cast(vb, Bti, Dti, -1);

You can even replace "__cxxabiv1::" by "abi::" in the above.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.