Path: utzoo!attcan!uunet!samsung!gem.mps.ohio-state.edu!tut.cis.ohio-state.edu!purdue!mentor.cc.purdue.edu!pur-ee!pur-phy!sawmill!mdbs!wsmith From: wsmith@mdbs.UUCP (Bill Smith) Newsgroups: comp.lang.c++ Subject: Re: Shippable C++ Objects (RFC) Summary: A possible solution to the problem Message-ID: <1467@mdbs.UUCP> Date: 21 Nov 89 23:39:05 GMT References: Organization: MDBS Inc., Lafayette, IN Lines: 94 >In article <4042@cadillac.CAD.MCC.COM> vaughan@mcc.com (Paul Vaughan) writes: > > Suppose that in the byte stream there is some token that uniquely > identifies the class of the the object being transmitted. Then that > token could be used to look up in a table a function to be called to > create such an object. So, you don't have to have a case statement > (other techniques are possible), but you do have to somehow know of > all interesting classes. A further technique would be to transmit a > pathname through the byte stream and to use that to dynamically load a > class definition. It would still be important to have a table of the > classes that were already loaded. > >An interesting idea! Is the capability of run-time loading of libraries of >objects supported within C++ yet? I would think that, in order for a program >to make use of an object, its declaration would have to be known to the >program at compile time. Therefore, I don't see how this could be done. :-( > >David Masterson Consilium, Inc. >uunet!cimshop!davidm Mt. View, CA 94043 This discussion has been wandering around an idea that I integrated into my MS thesis project, Leif. Leif only solved a problem defined in terms of C, but I think with the hints and ideas suggested this far, it could be extended to C++ without too much work. (If an implementor of C++ wanted to integrate something like this into the language, it might be even better. I'm not prepared to get involved with something as complex as that, yet I thought I should contribute the ideas anyway.) I'll try to give the problem statement that I tried to solve. It's a little different than the original problem we are discussing, but they are closely related: Problem: How does one store into a flat file a complex data structure, including arbitrary pointer references, with the provision that the file must be accessible (to some degree) arbitrarily into the future, even if the data structures of the loading program no longer match the definitions that were used to store the data. If I abstract the term "into a file" to be "to another address space", this more closely matches the shippable C++ objects problem. This technique, I believe, also solves a problem that Dr. Stroustrup references in the first edition of the C++ book: How can a compiler dynamically load symbol tables and other language definitions to allow more flexibility and better performance with commonly used libraries? Solution: First, define the data structures so that the type can be unambiguously detected from a pointer to the structure. In Leif, I put a word at the beginning of each structure. This was acceptable because I needed the field anyway for the most common structs in Leif. Also, I added a word that was used by the data structure traversal algorithms. In C++, the type definition field is free (just assume each class processed in this way has a virtual function for the purpose.) This extra traversal field may or may not be acceptable (but remember you can't get something for nothing). It might be possible to reduce it to a single bit per record, but I'm not positive on that. The problem is solved by traversing the structure in a fixed order(*) and then reconstructing it in the same order when the new copy is built. LL(0), LL(1) grammars and the like play no part in the algorithm and any arbitrary graph structure may be stored. At the header of the file is a description of the types stored so that they may be "formal"ly input, even if the classes describing the data are unknown to the loading program, preventing "casual" access. I don't really want to go through all of the gory details unless requested, but it works pretty well. It's not lightning fast, but I didn't really try to optimize it for speed either. I was more interested in being able to store a parse tree from one version of Leif and be able to retrieve the text even if the parse tree structure has been altered in an incompatible way, yet if the structure is still valid all of the data can be retrieved. This feature is also valuable in any rapidly changing software environment such as an object oriented program. Otherwise, just one change in one class and the stored data goes up in smoke... (Or you have a nasty version control problem that would make the cure about as bad as the disease.) You can get the source to Leif fairly easily (writing to leif@cs.uiuc.edu should be a way to get information). I think the module that implements this technique (and some related (IMHO) nifty activities) is in the directory dumpload. My MS thesis describes the method as part of one if its chapters but it's not a UIUC tech report yet as far as I know. :-( Let me know if you want a more clear description of the technique, but it seems a little pretentious to go into all the details if the solution doesn't meet a essential requirement that I haven't thought of. Bill Smith uunet!pur-ee!mdbs!wsmith (Not mdbs opinions...) (*) fixed order means that the order is set deterministically by the algorithm and the structure of the data, not that different data use the same order.