Does #pragma pack(n) apply to all the structures in a source code or it has to be applied to each structure separately ? It's not clear from the manual. In one place it says: "You can use #pragma pack(n) to make sure that any structures with unaligned data are packed." In other: "This pragma aligns members of a structure to the minimum of n"
It applies until any subsequent pragma pack(n) directive within the file is encountered.
Thank you, so if it will be the only one at the beginning of a module, it will apply to all the structures in a module, right ?
it will apply to all the structures in a module, right
It would indeed. Which is why you rather certainly do not want to do that. Too many people believe that #pragma pack were a good idea altogether. It's not. You're buying a minimal advantage in data size for the price of some serious problems in data handling, not the least of which is a waste of CPU cycles.
you rather certainly do not want to do that
I completely agree and trying to avoid it if possible. But let's consider the following scenario: I need to send a rather large (6KB) structure with mixed data types over the transmission channel. The structure should be reconstructed on the receiver end.
Possible solutions: 1. Extract all the data fields into continuous buffer and send it, then do the reverse operation on the receiver's end. But it's quite cumbersome. 2. Pack the structure and send it as a whole. The structure on the other end also should be packed. 3. Send the unpacked structure as a whole, and have a structure on the other end also unpacked. This is the way I would prefer. But how certain can I be that both the sent and reconstructed structures have exactly the same data alignment (both controllers are of the same type and the same toolset is used for both controllers) ?
2. Pack the structure and send it as a whole.
This is about the most popular wrong reason why people decide to pack structures.
It's wrong because you're only looking at one single aspect of that data structure's usage: sending it over the wire. But how do those data get into that structure? What else are you doing with it? In the end you'll typically pay more in terms of hassle and CPU cycles by working with an always packed structure than you would by packing the data for transport only. For starters you'll have to ensure that every single pointer ever accessing any element of that packed structure has the "packed" attribute, too. This tends to spread the hassle and waste of CPU all across the program.
And that's before you consider other transformations you may have to do at the interface to the outside world anyway (endianness, floating point format, bit field layout, ...). Those would kill the idea of "send it as it is" anyway, and remove what little advantage a packed structure might seem to have.
The morale: serialization is not a valid rationale for packing structures.
serialization is not a valid rationale for packing structures
thank you. i agree. And what is your opinion about the assumption that structures on both ends will have the same data alignment ?
"In the end you'll typically pay more in terms of hassle and CPU cycles by working with an always packed structure than you would by packing the data for transport only"
Been there; done that - never again!
"serialization is not a valid rationale for packing structures"
Agreed.
That is not an assumption that you should ever even think about making!
Even if you do happen to have a case where it is known (not assumed) that the two ends do just happen to have the same data alignment, it is probably still better to design as if they didn't.
If you rely upon it now, it is bound to change - and it will certainly be much harder to redesign everything retrospectively than it would have been to just do it "right" in the first place.
And, again, remember that alignment is not the only issue...
View all questions in Keil forum