Boost logo

Boost :

From: Robert Ramey (ramey_at_[hidden])
Date: 2002-11-14 01:12:46


>Vladimir Prus wrote:

...snip..

>> Suppose type_info where made portable - For example, suppose that a string containing
>> namespace, class name, and base class names were used. At first blush this might
>> seem to work. But the same class is used in another program in another
>> namespace so we better remove the namespace.

>How's that? I'm I going to use the class from two different problem, I'll use the
>same header, and the classes will be in the same namespace.

I'm refering here to a discussion in The C++ Programming Language sections 8.2.5
and section 8.2.8. Basically this illustrates how namespaces are used to
distinguish identically named classes imported from other projects. A namespace
is "prepended" to the class name to distinguish it from otherwise identically named
classes/functions. It the book, files are not included - but I view this as an attempt
to clarify the point. My point is that the "same" class might appear in different
namespaces in different programs, so namespace can't be part of the a cross
program "class identifier"

>However, the mention of GUID gives me a new ground for argumentation. Suppose *I* (i.e.
>without any help from serialization library), have created two maps:

> 1. type_info -> GUID
> 2. GUID -> factory function

>I believe this is enough to correctly serialize/deserialize all classes registered
>in those two maps. Your plug-in example suggests that load method for the base class
>should take care of saving GUID and load method should dispatch to the appropriate
>factory function. I think this only requires extra work from me, and is not needed.
>In fact, the library might care of it. If a class with declared GUID is saved, than
>GUID is safed as well. On loading, if object in archive has GUID, you call appropriate
>factory function and then proceed with loading into created object.

Ahhhhhhh - now you've hit the nail on the head.

My conclusion is that there can exist no universal function that automatically transforms
type_info into a GUID. This is the fundamental problem.

Suppose we set out to create such a function:

Permit me to include my argument for this point from a previous email

class name is insufficient as a cross program "class identifier" because its uniqueness cannot be
guarenteed. It follows that any function of class name would suffer the same problem.

Suppose we use something stronger - e.g. the whole class declaration.
That should be sufficent - Or is it?First of all this wouldn't permit
one to change class declarations with out changing its "identity".
Hence newer class versions couldn't be matched with older ones.
Class versioning (an indispensible concept) could not be implemented.
Besides, the fact that two declarations might be identical in no way
guarentees they have the same implementations accross programs.
So the above still applies. This leads to the conclusion that "class identity"
cannot be resolved merely by inspecting program header code
 - which is all the compiler can do. I believe that it is for this reason
that type_info was made "non-portable". Trying to make it portable would
serve no useful purpose.

There is no automatic way to assign "class identity".
It is a subjective concept that must be specified by the progammer

Now suppose you have a special situation. For example, a suite of programs
that are in you sole control and you would like to your own "Local cross program
class identifier". The above argument doesn't apply to this situation. For this
I created the example "demo_unregistered_pointers". In this case a GUID
consisting of type_info.name() would work just fine. Archives and code would be portabable
across all compilers. It would work even for plug-ins - as long as you had control
over the naming.

As an aside, I double checked into MFC as the details of how it addresses this issue.

Microsoft uses CRuntimeClass basically a wrapper around the class name. This
is written to the archive. On loading, they look it in the table. Basically using the
class name as the GUID. Since this system broke down for COM, the used
the Unique GUID generated by the computer.

My intention in the example was to illustrate give you the facility you want
without creating a more fundamental problem for others. Also consider that
this special serialization is required only for base classes of polymophic pointers
not for every class. typically this would be only a very small number

>As I was saying all the time, including all of the headers in the project in "main.cpp" is
>not a reasonable idea for me.

They don't have to be in main.cpp. you could include them a registeration.cpp
that has a function register_types which you call just after any archive
is created. At least it would all be in one place.

I have always understood your feelings about this. I sympathize with it as well.
I expended huge effort to overcome it - as I hope the explanation above illustrates.
Its not that I have been unwilling to address it. Its just that I have come to the
conclusion that its undoable for fundemental reasons.

I havn't given up - it may be possible to craft things such that there is a default
overridable system etc. But believe me its much more subtle than first appears.
As a matter of fact, I don't think anyone who hasn't done it can appreciate
the incredible amount of effort it takes to make a library such as this
given the very wide range of users with conficting design goals. Add to
this trying to make this work with compilers that have way too much
variation and you have a recipe to aggravation almost beyond human
capacity.

Note that I am posting a response to another user that touches this topic.
No doubt you'll be interested.

Robert Ramey


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk