August 16, 2002
On Thu, 15 Aug 2002 23:22:44 -0700 "Walter" <walter@digitalmars.com> wrote:

> Actually, autogenerated GUIDs should deliberately not be the same from compile to compile. Only if they are hardcoded will they be the same.

Then, you have a problem. You release version 1.0 of your program, end-users save documents made by it (and it uses persistence). Then, you release version 1.1 - and oops! it cannot read old files, because all the GUIDs were changed during recompile!

Hard-coding GUIDs for every class is a pain in the #@!. It should
be the compiler which does all the dirty work like this, not
the programmer.

I still don't understand, why not use the name of the class? What do you mean by "different versions of the class"?
August 16, 2002
On Fri, 16 Aug 2002 15:15:08 +0800 "anderson" <anderson@firestar.com.au> wrote:

> PS - Is it possible to get the name of a class as a string in C++?

typeid(Foo).name()

And I believe it is mangled.

August 19, 2002
"Pavel Minayev" <evilone@omen.ru> wrote in message news:CFN374844840487037@news.digitalmars.com...
> On Thu, 15 Aug 2002 23:22:44 -0700 "Walter" <walter@digitalmars.com>
wrote:
> > Actually, autogenerated GUIDs should deliberately not be the same from compile to compile. Only if they are hardcoded will they be the same.
>
> Then, you have a problem. You release version 1.0 of your program, end-users save documents made by it (and it uses persistence). Then, you release version 1.1 - and oops! it cannot read old files, because all the GUIDs were changed during recompile!
>
> Hard-coding GUIDs for every class is a pain in the #@!. It should
> be the compiler which does all the dirty work like this, not
> the programmer.

An alternate solution would be to write a ClassInfo.eq() function - classes
with the same ClassInfo
contents should be the same.

> I still don't understand, why not use the name of the class? What do you mean by "different versions of the class"?

Let's say, from version 1.0 to version 1.1, you add a member to the class without changing the class's name. Now, all binary references compiled with the old class layout will crash.


August 19, 2002
On Sun, 18 Aug 2002 22:17:50 -0700 "Walter" <walter@digitalmars.com> wrote:

> An alternate solution would be to write a ClassInfo.eq() function - classes
> with the same ClassInfo
> contents should be the same.

But, ClassInfo is practically a name, vtbl pointer, and constructor pointer.
So, it is simplier to store just the name. =)

> Let's say, from version 1.0 to version 1.1, you add a member to the class without changing the class's name. Now, all binary references compiled with the old class layout will crash.

This is "binary incompatibility", and there's just nothing you can do with
that. Only to remember not to break code so it can't read files generated
by earlier versions. After all, object can have some version property,
and check it when restoring itself from file, to catch this kind of errors.
But I don't see how you can _fix_ it.

August 19, 2002
"Pavel Minayev" <evilone@omen.ru> wrote in message news:CFN374878540987731@news.digitalmars.com...
> This is "binary incompatibility", and there's just nothing you can do with that. Only to remember not to break code so it can't read files generated by earlier versions. After all, object can have some version property, and check it when restoring itself from file, to catch this kind of
errors.
> But I don't see how you can _fix_ it.

At least by comparing the contents of ClassInfo, you'll know when you broke it <g>.


August 20, 2002
On Mon, 19 Aug 2002 16:35:23 -0700 "Walter" <walter@digitalmars.com> wrote:

> At least by comparing the contents of ClassInfo, you'll know when you broke it <g>.

ClassInfo contains a string (class name), initializer, and a couple of
pointers. It is probably not the best idea to save pointers to a disk
file...

August 20, 2002
Hi,

"Pavel Minayev" <evilone@omen.ru> wrote in message news:CFN374884983818403@news.digitalmars.com...
> ClassInfo contains a string (class name), initializer, and a couple of pointers. It is probably not the best idea to save pointers to a disk file...

Especially not with a garbage collecting language. However, saving pointers to disk may have its utility. I remember an application I wrote once. It had a small set of data structures fixed in memory, and a potentially very large data structure referencing the fixed data structure. The large data structure overflowed to a temporary file with pointers and all. It worked very well, and there was no reason it shouldn't, as the temporary file didn't live any longer than the fixed data structures.

Another programming practice I recall, that requires special attention with GC is this: Thread A creates a structure on the heap and sends a pointer to it to thread B over a message queue at OS-level, thereby having a queue with synchronization for free.

Regards,
Martin M. Pedersen




August 20, 2002
"Pavel Minayev" <evilone@omen.ru> wrote in message news:CFN374884983818403@news.digitalmars.com...
> On Mon, 19 Aug 2002 16:35:23 -0700 "Walter" <walter@digitalmars.com>
wrote:
>
> > At least by comparing the contents of ClassInfo, you'll know when you
broke
> > it <g>.
>
> ClassInfo contains a string (class name), initializer, and a couple of pointers. It is probably not the best idea to save pointers to a disk file...

ClassInfo will eventually be extended to know about the members and their offsets. An overloaded eq() for it would be able to follow the pointers and properly compare the contents.


August 20, 2002
On Tue, 20 Aug 2002 11:31:28 -0700 "Walter" <walter@digitalmars.com> wrote:

> ClassInfo will eventually be extended to know about the members and their offsets. An overloaded eq() for it would be able to follow the pointers and properly compare the contents.

But this means that ANY change to interface of class would make it "incompatible" to any previous version - which doesn't make sense if I just add a new function, or maybe a new property which isn't persistent.

So either it should use class name, and let the programmer control versions, or provide some way to indicate whether attribute is persistant or not. Something like this:

	class Mesh
	{
		Vertex[] vertices;
		Face[] faces;
		...
		// auto-generated OpenGL display list
		transient GLuint displist;
	}

But then it seems like a step to persistance built into the language
(which would IMO be great!).

By the way, anybody knows of some good reliable way to store object references into file, so they can be retrieved later?
August 21, 2002
"Pavel Minayev" <evilone@omen.ru> wrote in message
news:CFN374890214802662@news.digitalmars.com...
On Tue, 20 Aug 2002 11:31:28 -0700 "Walter" <walter@digitalmars.com> wrote:

> By the way, anybody knows of some good reliable way to store object references into file, so they can be retrieved later?

I'm sure this will be way below what your looking for.

--

In a previous project (I couldn't find the source), I built a tree (you
could of course use a hash table) of all the object references (well
pointers in C++) and saved them into the file.

It worked something like this.

To save...

Whenever the program came across a pointer the programmer would call this in
the save method of the object.
X = savePointer(char * Type, Object Pointer);
//Note that at this point I didn't know that you could get the names of
//objects using typeid(Foo).name().

X would return the number location in the tree the object existed. The X is saved in place where the pointer would be. If the object hadn't been saved yet, it would be saved on to a tempary store and inserted in the binary tree.

Finally.
saveAll( ... );
Would save the tree of tree of data and then all the object entries. At the
end of the file the main objects tree references are saved.

To load...

The tree is loaded, then each object in the tree is loaded (calling the
objects load method).
Finally fixPointers is called for each new object (note that at this stage
pointers are actually array indexes to the tree) which forces it to call
getPointer(reference) for each pointer it contains.

Finally all the linkages to the main program are set using
getPointer(reference) again.

Note that each object had a save and load function derived from a base class.

This technique is  reliable, but slightly complicated. Of course this technique could probably be improved in D (and probably even in C++). It would be nice if you could cycle though each property member in a class, determine if it was a pointer or not, and perform the appropriate action. That way this technique would only need to be written for the base class and all objects would inherit the ability to save themselves.