[prev in list] [next in list] [prev in thread] [next in thread] 

List:       koffice-devel
Subject:    Re: Portable Code (am I dreaming? :))
From:       Nicolas Goutte <nicog () snafu ! de>
Date:       2002-01-15 20:13:01
[Download RAW message or body]

On Tuesday 15 January 2002 01:25, Clarence Dang wrote:
> On Sun, 13 Jan 2002 21:54, shaheed wrote:
> > Hi Clarence,
> >
> > > Do I have to care about making filter code portable?
> >
> > I think you should. The MS Word filter started off (consciously, see
> > below) being little-endian and unaligned access dependent, and I soon
> > found that Ihad both Sparc and Alpha users. The MS Word filter has hooks
> > for both these platforms (see macro crap in mswordgenerated.h), but
> > amazingly enough, there are platforms for which the appropriate compiler
> > pragmas do not seem to exist (Irix and possibly HPUX).
>
> Just wondering but does #pragma pack(1) exist and work for all platforms?

No, it does not, as gcc is not the compiler of all platforms.

> I don't think it's ISO C++ but it's GNU so should work everywhere?
> I notice that you have:
> #ifndef __GNUC__
> #define __attribute__(a)
> #pragma pack(1)
> #endif
> So what do I, if I they're not using GNU (is anyone not?)?

Use the old portability trick: read byte per byte and calculate the variables 
yourself.

Please also note that with pack==1, you are generating unaligned accesses 
everytime you would access your structure. The structure must be packed like 
the CPU want it. You read one time from the file, but you access each 
variable many times (typically.)

>
> Also, is this portable:?

No! Size of int is unknown (could be 64 bits). Packing is unknown (the int 
could be aligned at addresses that can divide by 8.)

>
> FILE *filepointer;
>
> struct
> {
> 	int a;
> 	int b;
> } mystruct;
>
> fread (&mystruct, sizeof (int), 2, filepointer);
> if (mystruct.a == some_magic_number)
> 	do_something ();
>
> Will bit order affect the "mystruct.a == some_magic_number" test?

If you have bit order problems, you would have very big problems! I therefore 
suppose that you mean byte.

Yes, your test will be affected. (For example: 0x5300 could become 0x0053.)

If you want fully portable (non-QT) code, you would need something like 
reading four bytes and then calculate the two variables from them.

Something like:

 FILE *filepointer;

 struct
 {
 	int a;
 	int b;
 } mystruct;

 Q_INT8 helper[3];

 fread (&helper, 1, 4, filepointer);
 mystruct.a=helper[0]+256*helper[1];
 mystruct.b=helper[2]+256*helper[3];
 if (mystruct.a == some_magic_number)
 	do_something ();

Better use QT's QDataStream, like for example (not tested):

 struct
 {
	int a;
	int b;
 } mystruct;

 /* Add here some code to initialize the QDataStream stream */

 stream.setByteOrder(QDataStream::LittleEndian);
 Q_INT16 helper;
 stream >> helper;
 mystruct.a=helper;
 stream >> helper;
 mystruct.b=helper;

>
> > I finally started work to fix this (it is "easy" in my case because I
> > generated the code involved), but have not yet finished.
>
> How do I test my code, without having the target system?
> I only have ix86 systems.

No, idea! Sorry!

>
> > > With non-portable expressions like these, which make assumptions on
> > > data type sizes and byte ordering and bit ordering...
> >
> > The first step is to use Q_{U,}INT{8,16,32} as I believe you can trust
> > these to be set correctly on any platform. Then, QDataStream in little
> > endian mode may be your friend. If only I had known about these when I
> > started...
>
> Thanks for the information.
>
> Thanks!
> Clarence

I hope that I was able to help you a little.

Have a nice day/evening/night!

_______________________________________________
koffice-devel mailing list
koffice-devel@mail.kde.org
http://mail.kde.org/mailman/listinfo/koffice-devel
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic