[Box Backup] Workaround for struct packing problem on ARM processors (was: Another wish for 2011)

Leif Linderstam ell2 at live.se
Sat Feb 26 21:51:40 GMT 2011


Hi Chris,

> ... i.e. if we think we can make the packing directives
> do what we want (which looks doubtful).

Sit tight for a while and see what the result is of my tests with a newer
version of GCC, although it will probably take a couple of months before I
will have time to do that. As I understand it it is only I who have this
problem so far so in practice the portability is nearly good enough as it
is.

> I'd prefer not to import the whole of Boost to get assertion, and that
> page doesn't give me a definition, but I imagine something like this would
> work:
>
> #if sizeof(en_StreamFormatDepends) != 16
> #error Assertion failed
> #endif

That won't work because those are preprocessor statements, and sizeof() is
not computed at that stage and therefore not known by the preprocessor.

As far as I understand the very liberal license
(http://www.boost.org/LICENSE_1_0.txt) of most Boost libraries, including
Static Assert, it is perfectly alright to extract the files you want.
Actually it does not say that explicitly, but it says that derivative work
is okay. There are still several files that need to be extracted though
(the library handles quirks of many compilers). As far as I can see the
static assertion needs the following header files (most Boost libraries
consist only of header files):

  boost/static_assert.hpp
   boost/detail/workaround.hpp
  boost/version.hpp
  boost/type.hpp
  boost/non_type.hpp
  Every thing in directory boost/config/... (61 header files)

And then you also need the file LICENSE_1_0.txt to comply with the license.


Another slightly different approach is to do the check at runtime and abort
execution after issuing a fat message in the log if the size check fails.


> Regarding packing directives, this message:
>
  > http://www.mail-archive.com/debian-gcc@lists.debian.org/msg00435.html
>
> claims that there are two types of packing restrictions, controlled by
> different directives. The #pragma pack(1) apparently turns off padding
> within the structure, but not padding out of the structure length, which
> is what attribute ((packed)) should do. So I think we might need both in
> order for these structures to be 100% cross-platform. This is also
> completely not portable to other compilers than gcc.

That mail is quite old and if I understand the following mail correctly

  http://gcc.gnu.org/ml/gcc-patches/2006-10/msg01115.html

it seems that GCC has changed in order to be compatible with Win32, but I
am not sure.


> I'm thinking seriously about implementing your solution, but before we
> introduce another library for (de)serialising integer constants, I was
> wondering if you had seen Archive.h? Perhaps it can be extended with your

Well, I had not looked at Archive.h previously. It seems to do mostly what
we want although there are some differences that should be noted. First it
does not have any functions for writing and reading smaller integers than
32 bit, and at least 16 bit integers has to be supported.

Second it relies on overloading for determining the size and that might
lead to surprises. A seemingly innocent change of a local variable might
lead to a change of the network protocol and/or storage file format. Also,
conversions between integers are in most cases done silently with no
warnings. This is why I choose to name each function with the type it
actually writes or reads. That way the protocol format is more explicitly
defined.

Third the implementation of Archive is far more heavy-weight. Each integer
is written directly to the underlying stream which at least means that a
virtual function call is made, whereas the current implementation only
makes a store into memory for the same operation. My workaround tried to
mimic the speed of the current implementation, but suboptimization is
seldom good and if you think that it wont really affect the speed (the
actual I/O might be the bottleneck anyway) it is probably a better way to
go. If you choose this you might think about adding the write and read
functions to IOStream instead. I was thinking about doing that, but the
only way of doing it was to immediately call the virtual Write just as
Archive.h does it, and that was contrary to the design goal  I had of
mimicking the properties of the packed struct implementation as far as
possible.


> wondering if you had seen Archive.h? Perhaps it can be extended with your
> template for size safety? (Or we could just wrap it around a fixed size
> memory block that asserts if we read or write past the end).


The main reason for having a template with the size as parameter was to
mimic the current behaviour. This way the whole thing is allocated on the
stack just as the struct is, and nothing need to be allocated on the heap.
In addition it is possible to check that just the right amount of data has
been put into the message, but that is really not essential.
 

Cheers,
Leif

 		 	   		  


More information about the Boxbackup mailing list