Welcome, Guest. Please login or register.

Author Topic: GeneralSaver (was: Access to compiler's variable types possible ?)  (Read 6984 times)

Description:

0 Members and 1 Guest are viewing this topic.

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: Access to compiler's variable types possible ?
« on: December 21, 2006, 11:58:13 AM »
Don't forget that the size of each primitive will vary from architecture to architecture, as will alignment requirements and the endian representation of multibyte data, if platform portability is important.

In short, never rely on simply dumping a struct as binary data even if you are careful when handling pointer data. Even changing the compiler settings on the same target could cause changes in alignment which in turn could seriously alter the topology of your structure.

A much better approach, IMHO for plain C is to add a function pointer to your struct that points to the appropriate serialization functions to load/save that structure to an open filestream. A factory function that creates the structure would ensure that this function pointer is set:

Code: [Select]


typedef Foo struct {
  int someInteger;
  float someFloat;
  char someFixedCharData[8];
  Foo* next;
  Foo* prev;

  /* serialisation handlers, point to proper function at instansiation */
  int (*serialize)(const Foo* foo, FILE* fp);
  int (*unserialize) (Foo* foo, FILE* fp);

} Foo_t;


/* implementation detail */

int serializeFooInstance(const Foo* foo, FILE *fp)
{
/* serialization code specific to Foo here */
}

int unserializeFooInstance(Foo* foo, FILE *fp)
{
/* unserialization code specific to Foo here */
}

Foo* makeFoo(void)
{
  Foo* foo = (Foo*) malloc(sizeof(Foo));
  if (foo) {
    /* initialise all the members to safe defaults... */

    foo->serialize = serializeFooInstance;
    foo->unserialize = unserializeFooInstance;
    return foo;
  }
  return NULL;
}




You can then do a poor man's method call with the struct, rather like this:

Code: [Select]

FILE* fp;
Foo* myFoo;

....

myFoo = makeFoo();

...

if (fp = fopen(......)) {
  myFoo->serialise(myFoo, fp);
}


and so on.

The main point about this is that each structure type knows how to un/serialize an instance of itself.

Of course, if you follow this idea to it's logical conclusion, you'll ditch C and start C++ which gives you much more elegant ways of doing it ;-)
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: Access to compiler's variable types possible ?
« Reply #1 on: December 21, 2006, 12:00:12 PM »
I should further add that in all non-trivial cases, the physical cost of perfoming IO will be the performance limiting case, not the overhead in calling code to perform the appropriate serialisation of data.
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: Access to compiler's variable types possible ?
« Reply #2 on: December 21, 2006, 07:19:17 PM »
Quote

Cymric wrote:
The main problem Jose is facing is that there is no keyword (not in C, not in C++) which gives you back some structure outlining the variables and their type in a given scope.


Precisely why I suggest the OO approach. You can still have a set of functions that serialize primitive types based on their byte size that your structure serializers use to perform the physical IO.

This approach keeps the implementation well out of sight of the application code and allows  you to vary them indepentendtly.

I should add that it was the use of mechanisms like this that finally persuaded me to go C++ in the end anyway ;-)
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: Access to compiler's variable types possible ?
« Reply #3 on: December 21, 2006, 07:21:43 PM »
Quote

Jose wrote:
@Karlos
...
Regarding the alignment thing, didn't thought about that either :-) But I thought alignment of structures was made by padding bytes at the end or not ? If so, my method above would still work, though if there is a better one bring it on.
...


Well, alignment issues can cause structures to have holes in them. If your implementation prefers ints to be on a 32-bit boundary, the following structure would likely have a hole between the members:

struct Foo {
  short s;
  long l;
};

int p; // A