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

Compiler assumes array addresses are aligned for structs declared with __attribute__((packed))

If I have a struct declared like the following:

volatile struct {
    uint8_t foo;
    int16_t bar[1];
} __attribute__((packed)) foobar;

The code emitted uses LDRSH to access bar[0] and causes a hardfault at runtime. But If I were to declared it using the __packed qualifier:

__packed volatile struct {
    uint8_t foo;
    int16_t bar[1];
} foobar;

Then the compiler correctly recognizes the potential misalignment and emits LDRB instead. Is this the expected behavior? I'm using uVision v5.17 with Armcc v5.06 update 1 (build 61). Thanks.

Parents
  • Hello David,

    Did you see this entry in the manual:

    I assume you are using the --gnu or such in your Project-> Options for target -> "C/ C++ " tab, compiler control string, because based on this article:

    infocenter.arm.com/.../index.jsp

    It sounds like you are running into the scenario:

    In GNU mode, __attribute__((packed)) has the effect of #pragma packed. Taking the address of a field covered by __attribute__((packed)) does not produce a __packed qualified pointer.

    For more details, see:
    infocenter.arm.com/.../index.jsp

    There is good stuff there, but of particular interest is the "Comparison of a __packed struct and a #pragma packed struct" section. It looks simular to the issues you are having.

    A good work around may be to, rather than packing the whole struct, pack only the parts you care about (maybe just uint8_t foo;). There is a performance penalty for marking the whole struct as packed.

    infocenter.arm.com/.../index.jsp

    In my experience, packing the struct is something you only do if you are desperate for space - leaving the struct members at their natural data alignment makes it much simpler code. Also, there can be headaches when referencing pointers to pointers of a packed struct, if not done right.

    infocenter.arm.com/.../index.jsp

Reply
  • Hello David,

    Did you see this entry in the manual:

    I assume you are using the --gnu or such in your Project-> Options for target -> "C/ C++ " tab, compiler control string, because based on this article:

    infocenter.arm.com/.../index.jsp

    It sounds like you are running into the scenario:

    In GNU mode, __attribute__((packed)) has the effect of #pragma packed. Taking the address of a field covered by __attribute__((packed)) does not produce a __packed qualified pointer.

    For more details, see:
    infocenter.arm.com/.../index.jsp

    There is good stuff there, but of particular interest is the "Comparison of a __packed struct and a #pragma packed struct" section. It looks simular to the issues you are having.

    A good work around may be to, rather than packing the whole struct, pack only the parts you care about (maybe just uint8_t foo;). There is a performance penalty for marking the whole struct as packed.

    infocenter.arm.com/.../index.jsp

    In my experience, packing the struct is something you only do if you are desperate for space - leaving the struct members at their natural data alignment makes it much simpler code. Also, there can be headaches when referencing pointers to pointers of a packed struct, if not done right.

    infocenter.arm.com/.../index.jsp

Children
No data