|
|
View previous topic :: View next topic |
Author |
Message |
GWOULE
Joined: 12 Jan 2012 Posts: 2
|
struct alignment warning |
Posted: Thu Jan 12, 2012 7:02 pm |
|
|
Hi all,
Is there a way to manually align the elements of a struct in memory? Or maybe a way to declare the size of a struct to the compiler?
My issue is that when I have the following structures on execution they will throw an access error because the compiler (PCD 4.111) does not align the tMtrFlags on an even address. I can change to an understood type (unsigned int16) and some padding is inserted. Or I can re-arrange the struct so that it naturally falls on an even boundary.
But the question I have is is there any way to get an error or warning at compile time for this situation in future?? Seems kind of shifty to me that the compiler doesn't bother to check/align structs in this instance.
Thanks,
Grant
Code: |
typedef union {
unsigned int16 word;
struct {
unsigned char flag0:1;
unsigned char flag1:1;
unsigned char flag2:1;
unsigned char flag3:1;
unsigned char flag4:1;
unsigned char flag5:1;
unsigned char unused6:1;
unsigned char unused7:1;
unsigned char unused8:1;
unsigned char flag9:1;
unsigned char flag10:1;
unsigned char flag11:1;
unsigned char flag12:1;
unsigned char flag13:1;
unsigned char flag14:1;
unsigned char flag15:1;
} bits;
} tMtrFlags;
typedef struct
{
signed int32 locationStart;
signed int32 locationMid;
signed int32 locationCurrent;
unsigned char DirectionRequest;// Direction to move
tMtrFlags flags;
tMtrState state; // Motor State;
unsigned char direction;
} tMotor; |
|
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Fri Jan 13, 2012 5:01 am |
|
|
"kind of shifty" it might be, but you are not making the compiler's job any easier. You have a byte variable before the union in the wrapping structure. I try to avoid unions like this, where my assumptions about alignment and padding may be wrong, as indeed they are in this case.
You can try reordering the elements in the structure. I usually try to put the largest intrinsic types first, in this case the int32s, then any int16 and then fill the rest of the structure with chars and bits. Arrays are a problem, and its not at all clear how they will be aligned. What you've done by declaring DirectionRequest before the instances of tMtrFlags is to assume the compiler to sort out the alignment and add padding. This may well be a waste of memory for one thing (as the resulting structure will be at least one byte larger than it needs to be), and may add inefficiency to the code.
Also you have not named the type of the structure and union, yet you typedef them. Thius is pointless and may confuse the cokmpiler further. I have had instances, not in PCD though as I don't use it, of typedefed types causing trouble. I'd always name my types, and generally instance them separately, unless the are Highlander objects (there can be only one...). I think it makes more sense to define types, an then declare objects of that type rather than do borth at once. This though is primarily a matter of style.
I usually find that if I'm having to force the compiler to bend to my idea of how data should look, then I'm doing something seriously wrong and a architechtural review would be a good thing.
You might be trying to construct a union type or structure that "covers" a data stream, for instance to isolate the bits and parts of a data packet of some kind. There are so many pitfalls and portability issues (as in it won't be portable) that I've long since abandoned that idea. Far better all round to programmatically extract the section/bits/groups of bits and put them into my own structure that's optimised for the host and the application (i.e. if there a 3 bit address i'd put them into a int or something similar, even if it is far too wide).
RF Developer. |
|
|
GWOULE
Joined: 12 Jan 2012 Posts: 2
|
|
Posted: Fri Jan 13, 2012 10:55 am |
|
|
RF,
Thanks for the reply.
1) I completely agree with you with regard to trying to make the compiler's job easier. This is a simplified example and the issue occurred when I accidently added in the "DirectionRequest" late and everything broke loose. Of course, I did that along with other changes and did not think that the addition to the struct caused the trap.
2) With regard to the typedef and bits: CCS uses the short :1 bit structures all over the place to access hardware so I don't really see how to avoid that. Also, the code I posted does not instantiate any of the variables. You will still need to write tMotor MyMotor; or something equivalent to get a variable (MyMotor) of type tMotor. The typedef in this case creates an equivalent symbol "tMotor" for the struct - regardless of whether the struct is anonymous or not. This is just a personal preference to avoid having to type "struct" everywhere else.
3) Does anyone have the latest version of PCD and is willing to try this. Using the previous structure the added code of:
Code: | void Main(void)
{
tMotor MyMotor;
MyMotor.flags.word = 0;
} |
Should crash and re-boot the processor if "flags" was not aligned with an even boundary (and your trap ISRs are not coded). If this is still an issue I will report it as a bug/improvement to CCS. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|