On 1/13/2013 13:17, mathog wrote:
> Shao Miller wrote:
>
>> If you have implementation-specific knowledge of what will happen, then
>> I'd suggest that you do whatever you want to accomplish your goal.
>
> That's the point - I want this code to work wherever, without having
> access to all possible platforms to test it first. Implicitly
> implementation specific is exactly what I am trying to avoid.
>
>>
>> If you actually care about portability (you seem to), I'd suggest
>> formally serializing and deserializing data to and from the file.
>
> Yeah, I was afraid that was going to be the only standard compliant way
> of doing this. The key thing that I have learned is that passing a
> pointer to an unaligned structure isn't portable (6.3.2.3p7 cited by
> Eric Sosnan
(Sosman)
> earlier in this thread). There are some instances of that
> in the code that swaps bytes (big endian to little endian), so those
> routines will need to have their interfaces adjusted. They are
> otherwise "serial". Better to do this now, before the code is released,
> than later.
Based on what you've typed, I am guessing that the file format is not
intended to be portable across different platforms. Is that right?
That is, copying a saved file that was made on an x86 isn't expected to
load properly in the same program on PowerPC? I ask because the padding
within structures might also be a concern, for you.
By formally serializing/deserializing, you can have a portable file format.
> It also seems unavoidable that explicit recordtype_get()
> functions will be needed, with the data passed by void * or char *.
>
>> You might be interested in modern C, which is C11. It includes the
>> '_Alignof' and '_Alignas' keywords, which allow you to consider and
>> choose alignments, respectively.
>
> This doesn't help with the struct offset problem, since we do not know
> the offset ahead of time. In a particular file the struct could be
> anywhere in the buffer, at 100,102,..,500,502,etc. Or am I
> misunderstanding the purpose of the _Alignof and _Alignas?
Ah, no. If the structure can appear at any offset in the buffer, then
these don't help you as much, unless the offset happens to be a multiple
of the alignment requirement. But as mentioned, you can 'memcpy' from
the offset into an aligned location, which you might be interested in
doing anyway, if a structure can be truncated by being near the end of
your buffer.
At least you can automate some of the serializing/deserializing... You
can have:
struct s_foo {
double d;
int i;
char c;
};
size_t foo_offsets[] = {
offsetof(struct s_foo, d),
offsetof(struct s_foo, i),
offsetof(struct s_foo, c),
};
f_serialize * foo_serials[] = {
serialize_double,
serialize_int,
serialize_char,
};
where 'f_serialize' is a function typedef for a serialization function.
Then you can iterate through these arrays with a loop in a generic
"structure serialization" function, instead of having a monolithic:
void serialize_foo(struct s_foo * foo) {
serialize_double(&foo->d);
serialize_int(&foo->i);
serialize_char(&foo->c);
}
for each of your different structure types.
Or, here is one library you might be interested in:
http://www.leonerd.org.uk/code/libpack/intro.html
--
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.
Cheerily," -- Richard Harter