Structure sizes

Hello again.
I found some wacky difference between Neutrino and QNX4.x

The structure:

struct somestruct{
char somefield[25];
short firstshort;
short anothershort;
unsigned short nowunsignedshort;
unsigned int wealsohavethisinint;
unsigned int therearemore;
char onemorearray[120];
}

has in QNX4.x a size of 159 bytes.
AAAAAAAAAAAAAAAAAAAAAAAAABBCCDDEEEEFFFFGG…116*G…GG

in QNX 6.3 this has a size of 160 bytes.
(yes computers still cannot count again)
every type of is own reports right size. But in the structure a not-used byte is put after the first array:
AAAAAAAAAAAAAAAAAAAAAAAAA[color=red]XBBCCDDEEEEFFFFGG…116*G…GG

Any way to prevent this?
Or do i have to read data now for every member on its own?
I try to read this header from a file… it bugs now when reading the whole header at once.

It’s not a bug, it’s has to do with the default alignement. With watcom you can controle the behavior with #pragma pack() or the -z? argument, with GCC it’s with the __attribute feature.

I believe the C language does not have any requirement for alignement, any code that rely on such feature is not portable.

I get bitten by this on a regular basis. Move “somefield” to the bottom of the structure and the problem should go away.
For some processors, you cannot even access multibyte data that is misaligned, which might explain the lack of ‘C’ requirement.

It just bugs me :stuck_out_tongue:

No i cannot move the array down there. We have already about n-thousand files saved with this structure :slight_smile:
I do now read the structure-members single.

I think, the code was never meant to be portable to begin with. Its me who has to make it portable :stuck_out_tongue_winking_eye:

Thx.

Micro,

Do a:

#pragma pack(push, 1)
struct somestruct{
char somefield[25];
short firstshort;
short anothershort;
unsigned short nowunsignedshort;
unsigned int wealsohavethisinint;
unsigned int therearemore;
char onemorearray[120];
}
#pragma pack(pop)

to get a 1 byte alignment in gcc. That should let you read your structure as 159 bytes in QNX 6.

Tim

Well then you will need to tell the compiler that you want byte alignment for this structure.

Maschoen,

The pragma pack(push, 1) tells the compiler to use 1 byte alignment for the structure.

I’ve used this quite successfully with gcc 3.3.5 (not sure about earlier versions of gcc) and it gives me the 1 byte alignment I need. We have several external hardware devices from vendors that send structures via bytes over a serial line and this is how I get all the data into my structure without doing it field by field.

Tim

Yes, this works also for me very nice.

Thx :slight_smile:

I read a little bit about the alignment within gcc now,
there is stated to better not use #pragma for all.

I now implemented it with the attribute feature:

struct somestruct{
char somefield[25];
short firstshort;
short anothershort;
unsigned short nowunsignedshort;
unsigned int wealsohavethisinint;
unsigned int therearemore;
char onemorearray[120];
}
#ifdef QNXNTO
attribute ((packed))
#endif
;

I still wonder if i really need the #ifdef __QNXN… #endif part,
would WATCOM mind the attribute?

I also think about trying -fpack-struct. this should not have any negative consquences, shouldn´t it? I think this way it will be faster than checking a hell of thousand structures what needs to be packed and what not.

Thanks for help, once more :unamused:

Watcom doesn’t know about atrribute it’s a gcc specific keyword.

-fpack-struct is dangerous since it may create discrepencies between system header files and the librairies.

shouln´t -fpack-struct just affect my used structures? Why would there be than a danger if i use, for example, dirent-struct, since in my application all structs would be -fpack-struct.
Can you give me an example when -fpack-struct is going to exploit?

Exploit, that’s big of a term :slight_smile:

I have not tried this myself, but here is an example from the top of my head. Take the dirent structure, say that without -fpack-struct it’s 21 bytes and with -fpack-struct it’s 20 bytes (random numbers). Your code calls readdir, which expect a 20 bytes structures but the code to readdir is in the libc.so and was not affected by-fpack-struct. hence it will build a structures made up of 21 bytes.

thats a good example :slight_smile:
But shouldn´t the structures in libraries being filled single?
So every structure-member gets filled on its own?

Yey, im bit too lazy to perform attribute flag on n-thousand structures …
But maybe my problem with PxLoadImage now resides due to -fpack-struct…
Hell, i have to try so …

Yes and no, pack could save space, but at a cost of performance, on x86 it’s not too bad, but on some architecture it can get ugly.

You can use
#include <std/_pack1.h>

struct …

#include <std/_packpop.h>

It’s not portable but that should do the job.

Do you really need to do it on all n-thousand structures? There are only two times you should care about the size of the structure:

  1. You’ve hard-coded the struct’s size into function calls. Shame on you! You should have been using sizeof() to begin with. And I would suggest you go change the n-thousand places you’ve got these “magic numbers” rather than packing the structs themselves.

  2. You are overlaying the struct onto raw memory, e.g. to map a hardware device’s layout. In this case I would doubt that all n-thousand structs need to be packed. Surely you don’t have n-thousand hardware drivers?

-James Ingraham
Sage Automation, Inc.

There are other cases, data send over UDP/TCP or even over qnet ( if you don’t have access to the server side), binary files, etc.

  1. You are reading/writing the structure to disk, and some other program that reads/writes it assumes that is is packed.

This technique is not any better then “magic numbers” from first example and should be avoided IMHO. Just define macros which take pointer and add offset instead of using structures. This way you protect yourself that driver will work if compiled by different compilator, or porting the driver will require obvious work with defined macros for accessing the device layout than not-so-obvious playing around the structure attributes or pragmas.

If some program writes “whole structure” to disk and second program reads “whole structure” to memory, the situation could be worse. Simple because there are two programs any of which could be recompiled with different struct pack options and everything stop working.

Surely, all n-thousand structures should not be packed on byte boundary, because you may have perfomance penalty at the best, and good software should not care at all how structures are packed or located in memory.

Eduard

If you intensively work with these structures in your code later, I bet this your best option. Anyway, down the road, the data will be read from the disk in one chunk. Then you just tell driver to move some data from the driver’s buffer to some your location. If you don’t use packed structure, this location is good and will be no exceptions later to access any member; but you move only one member at once. If you use packed structure you move the data out of driver’s buffer at once, but location of some data may be not so good; and everytime you access that unfortunate structure member the CPU will generate an exception and exception handler will fulfit your request doing byte-by-byte copy. You program will work, but not as fast as it could.

On the reasons for packing a structure:

mario and maschoen both have points that (they admit) are all only issues when you don’t have both sides. True, I glossed over this point. I still think my main argument holds; you shouldn’t just go packing ALL of your structures. In a large code set (as we appear to be talking about) there may be some cases where you can’t live with the fact that the structure doesn’t look like what you want it to. But it shouldn’t be EVERY case.

Well, not macros. Functions and consts, maybe. You do have a point though. You could even load the offsets at run time to avoid recompiling for different architectures. Still, we’re talking again about an existing large code set. The guy doesn’t want to add attribute((packed)), which could be done programmatically. I doubt he wants to scrap the structs and go with functions.

Man, this is good stuff! Real world programmers sharing experiences. I’ve gotten more use out of the web in the last month because of OpenQNX they have the previous 10 years combined. (Well, not counting porn. :wink:)

-James Ingraham
Sage Automation, Inc.