This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

STM32F4 Problem with #pragma pack(x)

Hello,
Depending on the control #pragma pack(x), the result of the compilation is different.
In C++, Here's the problem, but it is more difficult without picture:

With #pragma pack(2), the result is Ok.

TNetCv::TNetCv(void)
{
  DCvPtrNetPtcl = Nil;
....
Compiling give:
0x0801A95C 2000         MOVS         r0,#0x00
0x0801A95E F8C40026      STR          r0,[r4,#0x26]

void TNetCvCOM::CvDoWhenNetEvent(ENUMNETEVENT TheCvEvent)
{
  TNetCv::CvDoWhenNetEvent(TheCvEvent);         // INHERITED
  switch(TheCvEvent)
  {
    case eNetEventRun:
      if (DCvPtrNetPtcl != Nil) DCvPtrNetPtcl->PtclDoWhenNetEvent(TheCvEvent);
    break;
  }
}
Compiling give:
    97:     if (DCvPtrNetPtcl != Nil) DCvPtrNetPtcl->PtclDoWhenNetEvent(TheCvEvent);
0x0801F782 F8D40026  LDR           r0,[r4,#0x26]
0x0801F786 B128      CBZ           r0,0x0801F794
0x0801F788 F8D40026  LDR           r0,[r4,#0x26]
0x0801F78C 6801      LDR           r1,[r0,#0x00]
0x0801F78E 6A0A      LDR           r2,[r1,#0x20]
0x0801F790 4629      MOV           r1,r5
0x0801F792 4790      BLX           r2

In both examples the offset of the pointer "DCvPtrNetPtcl" is 0x26

With #pragma pack(4), the result is Bad.

TNetCv::TNetCv(void)
{
  DCvPtrNetPtcl = Nil;
....
Compiling give:
0x0801A95C 2000         MOVS         r0,#0x00
0x0801A95E F8C40026      STR          r0,[r4,#0x26]


void TNetCvCOM::CvDoWhenNetEvent(ENUMNETEVENT TheCvEvent)
{
  TNetCv::CvDoWhenNetEvent(TheCvEvent);         // INHERITED
  switch(TheCvEvent)
  {
    case eNetEventRun:
      if (DCvPtrNetPtcl != Nil) DCvPtrNetPtcl->PtclDoWhenNetEvent(TheCvEvent);
    break;
  }
}
Compiling give:
    97:      if (DCvPtrNetPtcl != Nil) DCvPtrNetPtcl->PtclDoWhenNetEvent(TheCvEvent);
0x0801F3FE 6AA0      LDR           r0,[r4,#0x28]
0x0801F400 B120      CBZ           r0,0x0801F40C
0x0801F402 6AA0      LDR           r0,[r4,#0x28]
0x0801F404 6801      LDR           r1,[r0,#0x00]
0x0801F406 6A0A      LDR           r2,[r1,#0x20]
0x0801F408 4629      MOV           r1,r5
0x0801F40A 4790      BLX           r2

Without changing a line of code
Now, in the initialization is always offset 0x26, but in the second function the offset is 0x28. The result is an exception "UsageFault"

thank you for your help

Jean-François

Parents Reply Children
  • The OP said,

    "Depending on the control #pragma pack(x), the result of the compilation is different ... Without changing a line of code"

    So the OP expressed surprise that #pragma pack should alter the generated code.

    The reason compilers insert packing is to make the code "easy" for the target architecture - by aligning data to whatever that architecture "prefers".

    If you break that by forcing some other alignment using #pragma pack - or whatever - then it stands to reason that the compiler is going to have to adjust its output to accomodate your request.

    Hence I think it reasonable to point out that a change should be expected - it should not be a surprise.

    Further, great care is going to be needed that any pointer which points to a thing which has had its alignmend "messed-with" is fully aware of that, and does not just assume the "default" alignment - otherwise things like "UsageFaults" are to be expected...

  • And if I said that I thought a certain someone was annoyingly opinionated, would that be expressing surprise? or would it be expressing a fact?

    Unless you are the OP, you don't really know whether he is expressing surprise or a fact in that sentence. To me, what he writes at the start is showing a fact and later he asks the question about the resultant code.

    Unfortunately, I cannot provide specific help with his question and neither, it seems, can you.

  • My point is that you can't just arbitrarily change the alignment, and expect everything to "just work".

    I can speak from experience, having tried it!

    "... in contrast, taking the address of a field in a #pragma packed struct does not yield a __packed-qualified pointer. However, the field might not be properly aligned for its type, and dereferencing such an unaligned pointer results in Undefined behavior."
    (my emphasis)

    http://www.keil.com/support/man/docs/armcc/armcc_cjadhedh.htm

    I rest my case, m'lud.

  • My point is that you can't just arbitrarily change the alignment, and expect everything to "just work".

    I can speak from experience, having tried it!

    IMO that depends on how the code is written in the first place.

    Now if you expect your code to fail in this type of situation, it says more about your code, the way you write it and understanding of "how these things work".

  • Not at all. Assuming code works is what gives us all the broken software all around us. It is way better to assume the worst and spend a serious amount of time proving the code working.

    Note this article:
    http://www.keil.com/support/man/docs/armcc/armcc_BABCFBHC.htm
    So how many thinks about properly attributing their pointers after they pack their data?

    And it isn't part of the language standard. __unaligned is a similar keyword used by M$ to specify that a pointer points to unaligned data.

  • Assuming code works is what gives us all the broken software all around us.

    Errrmmm. FYI prior to this sentence, I have not used the word assume in this thread!

    Careful, inaccuracy is also a major cause of broken software.

  • And you haven't seen my make such a claim either. So back to you - and be careful with your assumptions.

  • Not at all.

    Oh Per, how your style has changed over the years.

    Maybe you should relax for a while. Maybe you could go for a walk in the woods. Maybe you'd be better to consider what you do and say. Maybe it would be best not to assume that where you go is free of traps.

    Enjoy the rest of the weekend ;)

  • So - why is it so important for you to move the focus away from packed/unaligned data?

  • So - why is it so important for you to move the focus away from packed/unaligned data?

    Important? Not to me. But, there again, importance is a relative term.