Search code examples
gccandroid-ndkarmalignmentgcc-warning

__packed qualifier ignored


Why I get a '__packed__' attribute ignored [-Wattributes] warning in an android NDK Project?

Here is the code

    mem_ = malloc(size_);

    uint8_t* ui8_ptr = reinterpret_cast<uint8_t*>(mem_);
    *ui8_ptr++ = packet_version;

    //uint32_t* ui32_ptr = reinterpret_cast<uint32_t*>(ui8_ptr);
    __packed uint32_t* ui32_ptr = (__packed uint32_t*)(ui8_ptr);
    *ui32_ptr++ = size_;
    *ui32_ptr++ = flags;

I am using the packed attribute because I think I have alignment problem when casting from uint8_t to uint32_t (See [1]).

[1] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka15414.html


Solution

  • GCC doesn't seem to support the packed attribute for all variables. It is only supported for struct, union, and enum types. So you could try something like this instead:

    mem_ = malloc(size_);
    
    uint8_t* ui8_ptr = reinterpret_cast<uint8_t*>(mem_);
    *ui8_ptr++ = packet_version;
    
    struct unaligned32_t
    {
        uint32_t data __attribute__((packed, aligned(1)));
    };
    //unaligned32_t* ui32_ptr = reinterpret_cast<unaligned32_t*>(ui8_ptr);
    unaligned32_t* ui32_ptr = (unaligned32_t*)(ui8_ptr);
    (ui32_ptr++)->data = size_;
    (ui32_ptr++)->data = flags;
    

    This won't produce the warning unless you use it on a char type, which is already byte aligned anyway.

    I'm still investigating if this produces the code I'm aiming for on my ARM micro-controller but it is the only legal way I can think of using the packed attribute.

    Here be dragons! Don't take the address of unaligned32_t.data. You should only access the data member of the struct using the . or -> directly, and not via a pointer. See this answer for why.