[GCC-XML] Xrtti.h
Wesley Tansey
tansey at vt.edu
Thu Apr 26 23:00:36 EDT 2007
I was waiting for someone to ask that question, as it took us about a
week of mind-racking to come up with a solution. Unfortunately, since
it's one of the key novel contributions for our work, I can't release
the details until after the June 4th ASE submission deadline. I hate
having to keep certain things a secret, but suffice it to say that when
we do release it, you'll definitely get an "ah-ha!" moment (after
spending about an hour trying to figure out what the heck is going on). :)
However, for a temporary solution, why not use the friend keyword? That
was our initial idea. Also, for #5 I know of at least one tool, C++2MPI
(not based on GCCXML), which does something very similar but slightly
tweaked due to the way that MPI works.
Wesley Tansey
Graduate Student
Department of Computer Science
Virginia Tech
http://people.cs.vt.edu/~tansey/
Bryan Ischo wrote:
>> Bingo. For static arrays this obviously isn't necessary, but for
>> dynamically allocated arrays, the user can specify a field which will be
>> the count.
>>
>
> There is another troubling aspect to generating serializer functions,
> which I forgot to ask you about previously.
>
> When a method is generated to serialize an instance of a given class, and
> the function which is thus generated exists outside the class definition
> itself, the generated function will not have access to private member
> variables of the class.
>
> So for example if you have a class:
>
> class Foo
> {
> public:
>
> int a;
>
> private:
>
> int b;
> };
>
> Then if you generate a serializer function that looks something like this
> (pseudo-code):
>
> void SerializeFoo(const Foo *pFoo, Serializer &serializer)
> {
> serializer << pFoo->a;
> serializer << pFoo->b;
> }
>
> When this code is compiled, it will fail, because the SerializeFoo
> function does not have access to the private member variable Foo::b.
>
> I can see five ways around this:
>
> 1. Require that the serialize functions thus generated be part of the
> class itself; so that you require that the developer add a signature "void
> Serialize(...)" to their class, and your tool just generates the method
> definition to fill in "Foo::Serialize(...)". In this way, the developer
> is giving the method that you generate access to all private data members.
> The problem with this approach is that it requires that
> serialize/deserialize method signatures be added to every class by the
> developer.
>
> 2. Don't allow private member variables in classes to be serialized. This
> is pretty unpalatable though because it doesn't allow developers to use
> access keywords to enforce encapsulation in their code. Essentially,
> developers can never use "protected" and "private" member variables.
>
> 3. Require the developer to make their "protected" and "private" member
> variables conditional upon some preprocessing macro that gives access to
> these members only to your generated code. For example, require the
> developer to do something like this:
>
> class Foo
> {
> public:
>
> int a;
>
> #ifndef SERIALIZER
> private:
> #endif // SERIALIZER
>
> int b;
> };
>
> The above would mean that for all definitions of Foo seen by all code
> that the developer writes, "b" would be private in the class above.
> Only the code generated by the serializer tool would #define SERIALIZER,
> and thus have access to private members. This has the disadvantage of
> making for some really, really ugly and error prone class definitions.
>
> 4. #define private public & #define protected public, in the code that is
> generated by the serializer, before #including the header file that
> defines the classes to be serialized. This is a really cheesy way to
> basically break the rules of C++ (I believe the C++ standard specifically
> says that code is not ever supposed to do this) and "promote" the
> generated code to have full access to all members of the class.
>
> 5. Have the serializer-generator also generate "proxy" classes which
> mirror exactly the classes to serialize, except they define everything
> public. Thus the serializer would output a "FooProxy" class definition
> that looked exactly like the "Foo" I described above, except that it would
> start with public: access and never set anything private. Then the
> serializer would, to serialize a Foo, first cast it to a FooProxy, and
> serialize that.
>
> Believe it or not, my code generating tool, xrttigen, uses option (4).
> It's really hacky and I have to wonder if it will work with all compilers.
> But it works great with gcc!
>
> There is a minor caveat: you also have to #define class struct. This is
> so that you get access to private member variables of classes for which no
> access was specified, and thus defaulted to private. If you turn those
> into structs (which from my understanding of C++, is exactly equivalent,
> except that the default access becomes public instead of private), then
> you solve this problem. Unfortunately, when I do this, I find that some
> obscure C++ header files (especially those in the C++ std library) break
> in ways I don't understand.
>
> If 4 ends up being too problematic, I think I will re-implement using 5.
>
> Just wondering how you tackle this problem.
>
> Thanks,
> Bryan
>
>
> ------------------------------------------------------------------------
> Bryan Ischo bryan at ischo.com 2001 Mazda 626 GLX
> Hamilton, New Zealand http://www.ischo.com RedHat Fedora Core 5
> ------------------------------------------------------------------------
>
>
> _______________________________________________
> gccxml mailing list
> gccxml at gccxml.org
> http://www.gccxml.org/mailman/listinfo/gccxml
>
>
More information about the gccxml
mailing list