memmove

Hello eveyone
I started porting an application from windows to QNX. So I’m very new in QNX development !!
I’ve a problem which started to give me headache :

I try the following code :

struct test{
_uint8 mByte;
_uint32 mInt;
_uint8 mByte2;
_uint8 mByte3;
_uint8 mByte4;
};

char mTmpArray[8] = {0x0D, 0x42, 0x63, 0x00, 0x00, 0x50, 0x72, 0x65};

test* mEnv = (test*)malloc(sizeof(test));
memmove(mEnv, mTmpArray, 8);

I should have :

mByte = 0x0D
mInt = 0x00006342
mByte2 = 0x50
mByte3 = 0x72
mByte4 = 0x65

but I have

mByte = 0x0D
mInt = 0x65725000
mByte2 = 0
mByte3 = 0
mByte4 = 0

What is wrong in my code ?
Thanks in advance
Arnaud

This issue is alignment. It is more efficient handling 32 byte words that are aligned on a 32 byte boundary so some compilers will by default insert bytes. If you want the code to work as before you will have to “pack” the structure. This will make it slightly less efficient to access. This may help:

gcc.gnu.org/onlinedocs/gcc/Struc … agmas.html

To simplify what Maschoen wrote:

#pragma pack(push, 1)
struct test{
_uint8 mByte;
_uint32 mInt;
_uint8 mByte2;
_uint8 mByte3;
_uint8 mByte4;
};
#pragma pack(pop)

will let your code behave as you expect.

Tim

Alternately:

struct test{
_uint8 mByte;
_uint32 mInt;
_uint8 mByte2;
_uint8 mByte3;
_uint8 mByte4;
}attribute((packed));

Another strategy that is often employed (although it won’t work with your code without rearranging the data in mTmpArray is to put the larger fields first:

struct test{
_uint32 mInt;
_uint8 mByte;
_uint8 mByte2;

}

This will automatically pack the structure, causes no lost off efficiency, and needs no compiler dependent code changes.

Another option is to pass -f pack-struct to the compiler. Hey! As I remember, gcc has a bug when compiling in C++ and does not recognize this flag (thanks God the #pragma still works fine). This issue made me scare few years ago migrating C++ code from QNX 4 to QNX 6…

I don’t know if it’s solved in gcc 4.2.4 …

JM

Yes it is !! :smiley:

Actually you don`t want to use that flag, these reason it that it will also pack OS header files structures possibly rendering them incompatible with the C or C++ library.

Hum… interesting point… I used this flag many times with no problem, but it’s certanly correct your observation… I’d like to try some case when this happens… because it’s strange for me that I’ve never had a problem with this… even in complex codes compiled in this way and definitely using structures defined in OS headers…

You can only have a problem in code in which you directly use the structures. It will also only occur if the structures cause alignment issues. For example, this will not cause a problem;

struct {
char byte[1];
char byte2;
unsigned short short1;
long long1;
};

I had problems with streams stuff if my memory serves me right. However with correctly defined header files this should not be a problem. Maybe this is a problem that was addressed in 6.4.1 header files, they could be oblivious to such a setting.

Oh also for increased portability you might want to have the #pragma embedded inside a header file, that way if you change compiler or platform it will be easy do deal with.

QNX does it with <_pack…> however the leading _ means it’s internal and should not be used.

anyway… most compilers supports this kind of structure padding options, isn’t?

thanks for these answers !
It works perfectly

Never use -f pack… as compiler option, easiest example is file-selection dialog or file-tree dialog. These will crash, since the library does not work with packed structures. We had a lot of trouble with this too, see the links under the text. You may also find some other pretty strict things about gcc.

Packed Structures

Structure Types Definition