Hi, I trapped in with the following: #pragma pack(1) typedef unsigned char uc_String[21]; typedef struct { unsinged char uc_MsgCmd; }
Sorry, the mail was incomplete, here I go again... Can anybody tell me if I'm going wrong or maybe trapped into a compiler error? I trapped in with the following: //------------ Header File --------------- #pragma pack(1) typedef unsigned char tauc_String[21]; typedef struct { unsinged char uc_MsgCmd; tauc_String auc_String; }tst_PackedStruct; typedef tst_PackedStruct tast_PackedStructArray[2]; #pragma pack() //------------ C-Source ------------------ #include "Header File.h" tast_PackedStructArray ast_PackedStructArray = {0}; void TestFunc (void) { // the result in i will be 24 -> WRONG int i = sizeof(tst_PackedStruct); // the result in i will be 24 as well, // don't care to much but to me this seems to be wrong to. i = (unsigned char *) &PackedStructArray[1] - (unsigned char *) &PackedStructArray[0]; }
Adrianes den Toom wrote: >... > #pragma pack(1) >... > #pragma pack() As far as I know gcc does not support a pack pragma. Did you read the gcc-Documentation about variable-attributes ( _attribute_ ((packed)) )? Martin Thomas
#pragma directives are always compiler specific (I imagine that you wuld have got at least an unsupported pragma warning at compilation). Moreover the devlopers of GCC have made a concious decision to avoid implementing any #pragma directives where possible. Refer to http://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Function-Attributes.html#index-g_t_0040code_007b_0023pragma_007d_002c-reason-for-not-using-1835 for the justification, and http://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Variable-Attributes.html#index-g_t_0040code_007bpacked_007d-attribute-1860 for the solution. Clifford
Clifford Slocombe wrote: > #pragma directives are always compiler specific (I imagine that you wuld > have got at least an unsupported pragma warning at compilation). > Moreover the devlopers of GCC have made a concious decision to avoid > implementing any #pragma directives where possible. > > Refer to ... Hi Clifford, thanks for your info. But: 1. There are no warnings about the #pragma pack(1) / #pragma pack() directives. 2. If it had no effect the structure being affected the following: typedef unsigned char tauc_String[21]; typedef struct { unsinged char uc_MsgCmd; tauc_String auc_String; }tst_PackedStruct; ought result in a structure of 4 + 24 Bytes -> 28 Bytes, due to the alignment of both elements... 3. _attribute_ ((packed)) will result in gcc-arm-elf 4.1 telling you that it is ignoring the attribute when applied to typedefs or variable declaration. Of course this only makes 'real' sense if it is applicable to typedefs as well. The structures are used for communication with other machines and being sent over different interfaces... I need them packed to make the communication modules work at all, if not the MSG format of Arm systems is incompatible with existing systems, although structures are the same... (big Endian / little endian is annother issue of course...) regards, A. den Toom
Adrianes den Toom wrote: > 3. _attribute_ ((packed)) will result in gcc-arm-elf 4.1 telling you > that it is ignoring the attribute when applied to typedefs or variable > declaration. Of course this only makes 'real' sense if it is applicable > to typedefs as well. OK,- it should look like this: typedef struct _attribute_ ((_packed_)) { ... } tst_SomeStruct; THIS does work with WINARM 4.0.2 and probably with 4.1.0, too. regards. A. den Toom
> 1. There are no warnings about the #pragma pack(1) / #pragma pack() > directives. Yes, sorry, I checked the manual you need the -Wunknown-pragmas option, this is not set by -Wall. > 2. If it had no effect the structure being affected the following: > ... > 3. _attribute_ ((packed)) will result in gcc-arm-elf 4.1 telling you > ... It perhaps would have been useful if you had posted the code with your attempt at using __attrubute((packed)), rather than the original code. However perhaps Mr. den Toom has solved it for you. > The structures are used for communication with other machines and being > sent over different interfaces... > I need them packed to make the communication modules work at all, if not > the MSG format of Arm systems is incompatible with existing systems, > although structures are the same... (big Endian / little endian is > annother issue of course...) You may solve the packing problem in this way, but you will find that the endianness solution is less straightforward, and renders the packing solution irrelevent. To solve both the endian and packing issue, it is normal to use a serialiser/deserializer routine, so that you send each field byte-by-byte in your chosen order rather than sending whole structures which may not match between different platforms. It may seem a lot of work, but it is much more portable and robust under maintenance; so it pays dividends in the end. C++ is particularly suited to this approach because the serialise/deserialise routines can be member functions of the data class you want to transmit (and you can loose all that typedef nonsense ;-) ). The same routines are useful for saving objects to disk also. Clifford
Clifford Slocombe wrote: >> 1. There are no warnings about the #pragma pack(1) / #pragma pack() >> directives. > Yes, sorry, I checked the manual you need the -Wunknown-pragmas option, > this is not set by -Wall. yes, maybe, but why does it evaluate to 24 instead of 28 with the Winarm gcc 4.0.2? Remember, both - the unsigned char and the unsigned char[21] should then be aligned to 4 Byte boundary. Resulting in 4 bytes for the uchar and 24 Bytes for the uchar[]. I spoke to a colleague who compiled the 4.0.2 himself and he gave me the executables,- they seemed to work out of the box with the #pragma pack(1) directive and evaluated the size to 22 ... He claimed to have it taken right from the gnu archive and swore not to have modified anything. > It perhaps would have been useful if you had posted the code with your > attempt at using __attrubute((packed)), rather than the original code. > However perhaps Mr. den Toom has solved it for you. well, thats me in both cases :-). > You may solve the packing problem in this way, but you will find that > the endianness solution is less straightforward, and renders the packing > solution irrelevent. yes, you're dammned right :-). > To solve both the endian and packing issue, it is > normal to use a serialiser/deserializer routine, so that you send each > field byte-by-byte in your chosen order rather than sending whole > structures which may not match between different platforms. I agree, but I have to code in C... Still this does not mean that in C it is impossible to write clean serializer and deserialisers. But I'm also bound to the directives given to me,- not to touch the old code if there is any chance to avoid it. Furthermore I just have to code a rather small subset of messages, so I decided to go for the structured version and put it on top of the existing code. Anyway, thanks for your hints, they put me on the right track to solve my issue. regards, A. den Toom
Adrianes den Toom wrote: > Clifford Slocombe wrote: >>> 1. There are no warnings about the #pragma pack(1) / #pragma pack() >>> directives. >> Yes, sorry, I checked the manual you need the -Wunknown-pragmas option, >> this is not set by -Wall. > > yes, maybe, but why does it evaluate to 24 instead of 28 with the Winarm > gcc 4.0.2? > Remember, both - the unsigned char and the unsigned char[21] should then > be aligned to 4 Byte boundary. Resulting in 4 bytes for the uchar and 24 > Bytes for the uchar[]. You cannot maks such assumptions about byte alignment unless you have explicitly specified a particular alignment. The compiler is free to align data in any way it chooses - to suggest the alignment was 'incorrect' is itself incorrect. Typically alignment is used to achieve optimal code generation for performance. The actual alignment will depend on the compiler, the target, and the compiler options. For example setting the ARM architecture, and/or thumb mode options makes different instructions available. If the processor can perform 16bit writes as efficiently as 32, then the likley alignment will be 2. I once wrote some FLASH memory managment that failed to work - it turned out that in ARM7 mode, the compiler generated 16bit writes from two 8bit instructions, which resulted an invalid programming sequence, setting it corretly to ARM9 fixed the problem. > > I spoke to a colleague who compiled the 4.0.2 himself and he gave me the > executables,- they seemed to work out of the box with the #pragma > pack(1) directive and evaluated the size to 22 ... > He claimed to have it taken right from the gnu archive and swore not to > have modified anything. There may be many reasons for this as explained, but #pragma pack(1) was not one of them. More by luck than judgement I would suggest. >> It perhaps would have been useful if you had posted the code with your >> attempt at using __attrubute((packed)), rather than the original code. >> However perhaps Mr. den Toom has solved it for you. > > well, thats me in both cases :-). > Oh, yes, sorry. You only latterly started signing at the bottom, and you seemed to be answering your own question! Good luck. And remember anyone that tells you that C++ is unsuitable for embedded systems is wrong! ;-) Clifford
Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
Log in with Google account
No account? Register here.