public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Multiple Abstract (contd)
@ 2003-09-11  2:21 Jacob Smith
  2003-09-11  3:08 ` Burak Serdar
  0 siblings, 1 reply; 2+ messages in thread
From: Jacob Smith @ 2003-09-11  2:21 UTC (permalink / raw)
  To: GCC HELP

BTW, I'm trying not to stray too deeply into "how to program C++": I'm 
wondering about implementation specifics of GCC 3.X vs. the standard.

I found the notes about virtual functions and vtables at 2.5.5, a little 
more in 15.2/X in the standard. My question is if my solution to the 
problem (I include my the code at the end) only works for GCC 3.3.1 (and 
similar) or if there is further standardization of the vtable layout 
which isn't in the Stroustrup reference or, even better, I'm missing 
something obvious like static_cast<> etc. Basically, the layout I'm 
seeing is this:
class A /* virtual abstract base class*/
class B /* virtual abstract base class*/
class C : public A, public B /* concrete class, known only during 
compilation, not "before" or "after" - no typedefs etc. possible */
Layout of C
[pointer to vtable:A, sizeof(void*)][pointer to vtable:B, 
sizeof(void*)][data... sizeof(...)]
Using offsets into the layout of a class is an ugly hack and I was 
hoping for a more C++ish solution. Note that I can't get around the 
hashing of the pointer (the actual call is for the WNDCLASS{EX} in Win32 
using the cbWndExtra set to a pointer and a push of SetWindowLong and a 
pop of GetWindowLong). If the answer is "that's what you get for mixing 
old-school C with C++", that's fine. Also, note that the class type for 
the equivalent of class C is generated at compile-time, after I'm done 
"programming" - the type is unkown when I'm physically *typing* the code.
-j.

Burak Serdar wrote:

> If GetHashedValue() is a function that allocates an instance of class 
> concrete, and returns a char * (+4?), this is the correct behavior, as 
> the type cast is not safe. The +4 offset accounts for the vtable 
> pointer  of 'base_1', aligning a 'concrete' pointer to be a 'base_2'.


/* this function correctly creates an interface, given the concrete 
class C, and the type-list of inherit types */
template < typename T, typename type_list_T >
T& interface ( void *ptr ) {
   return *((T*)(ptr) + type_search<T,type_list_T>::result);
};
/* this is the declaration of type_search, going beyond the bounds 
returns N for an array of size N, or "one beyond the end" value */
template < typename search_T, typename type_list_T >
struct type_search;    // root inherit type
template < typename search_T >
struct type_search< search_T, type_terminator > {                    // 
result is based at 0
   enum { result = 0 };
};
template < typename search_T, typename U >
struct type_search< search_T, type_list<search_T,U> > {            // 
found what we're looking for
   enum { result = 0 };                                                
   // result is based at 0
};
template < typename search_T, typename T, typename U >
struct type_search< search_T, type_list<T,U> > {                    // 
searching at case N
   enum { result = 1 + type_search<search_T,U>::result };            
       // add 1, look in tail
};

/* defines a type-list */
template < typename T, typename U >
struct type_list {
   T head;
   U tail;
   typedef T head_T;
   typedef U tail_T;
   typedef type_list<T,U> type_list_T;
};
/* also code to generate a class which inherits every type of a 
type-list, sort, append, erase etc. etc. */

The type-lists are derived from the algorithms/data structures in 
"Modern C++ Design", Andrei Alexandrescu, 2001, Addison-Wesley etc. etc.



^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Multiple Abstract (contd)
  2003-09-11  2:21 Multiple Abstract (contd) Jacob Smith
@ 2003-09-11  3:08 ` Burak Serdar
  0 siblings, 0 replies; 2+ messages in thread
From: Burak Serdar @ 2003-09-11  3:08 UTC (permalink / raw)
  To: Jacob Smith; +Cc: GCC HELP

I don't know what the standard mandates in terms of class layout in 
multiple inheritance, so I can't comment on that. Nevertheless, you can 
get rid the offset addition by introducing a class derived from base_1 
and base_2, and deriving C from that composite class. The composite has 
to be known, and C can still be declared using the type_list templates. 
This way, you can at least know the base of C while *typing* the code.

Jacob Smith wrote:
> BTW, I'm trying not to stray too deeply into "how to program C++": I'm 
> wondering about implementation specifics of GCC 3.X vs. the standard.
> 
> I found the notes about virtual functions and vtables at 2.5.5, a little 
> more in 15.2/X in the standard. My question is if my solution to the 
> problem (I include my the code at the end) only works for GCC 3.3.1 (and 
> similar) or if there is further standardization of the vtable layout 
> which isn't in the Stroustrup reference or, even better, I'm missing 
> something obvious like static_cast<> etc. Basically, the layout I'm 
> seeing is this:
> class A /* virtual abstract base class*/
> class B /* virtual abstract base class*/
> class C : public A, public B /* concrete class, known only during 
> compilation, not "before" or "after" - no typedefs etc. possible */
> Layout of C
> [pointer to vtable:A, sizeof(void*)][pointer to vtable:B, 
> sizeof(void*)][data... sizeof(...)]
> Using offsets into the layout of a class is an ugly hack and I was 
> hoping for a more C++ish solution. Note that I can't get around the 
> hashing of the pointer (the actual call is for the WNDCLASS{EX} in Win32 
> using the cbWndExtra set to a pointer and a push of SetWindowLong and a 
> pop of GetWindowLong). If the answer is "that's what you get for mixing 
> old-school C with C++", that's fine. Also, note that the class type for 
> the equivalent of class C is generated at compile-time, after I'm done 
> "programming" - the type is unkown when I'm physically *typing* the code.
> -j.
> 
> Burak Serdar wrote:
> 
>> If GetHashedValue() is a function that allocates an instance of class 
>> concrete, and returns a char * (+4?), this is the correct behavior, as 
>> the type cast is not safe. The +4 offset accounts for the vtable 
>> pointer  of 'base_1', aligning a 'concrete' pointer to be a 'base_2'.
> 
> 
> 
> /* this function correctly creates an interface, given the concrete 
> class C, and the type-list of inherit types */
> template < typename T, typename type_list_T >
> T& interface ( void *ptr ) {
>   return *((T*)(ptr) + type_search<T,type_list_T>::result);
> };
> /* this is the declaration of type_search, going beyond the bounds 
> returns N for an array of size N, or "one beyond the end" value */
> template < typename search_T, typename type_list_T >
> struct type_search;    // root inherit type
> template < typename search_T >
> struct type_search< search_T, type_terminator > {                    // 
> result is based at 0
>   enum { result = 0 };
> };
> template < typename search_T, typename U >
> struct type_search< search_T, type_list<search_T,U> > {            // 
> found what we're looking for
>   enum { result = 0 };                                                  
> // result is based at 0
> };
> template < typename search_T, typename T, typename U >
> struct type_search< search_T, type_list<T,U> > {                    // 
> searching at case N
>   enum { result = 1 + type_search<search_T,U>::result };            
>       // add 1, look in tail
> };
> 
> /* defines a type-list */
> template < typename T, typename U >
> struct type_list {
>   T head;
>   U tail;
>   typedef T head_T;
>   typedef U tail_T;
>   typedef type_list<T,U> type_list_T;
> };
> /* also code to generate a class which inherits every type of a 
> type-list, sort, append, erase etc. etc. */
> 
> The type-lists are derived from the algorithms/data structures in 
> "Modern C++ Design", Andrei Alexandrescu, 2001, Addison-Wesley etc. etc.
> 
> 
> 
> 

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2003-09-11  3:08 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-09-11  2:21 Multiple Abstract (contd) Jacob Smith
2003-09-11  3:08 ` Burak Serdar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).