0

When adding the -Wpacked option to arm-none-eabi-gcc combiler it issues the following warning:

warning: packed attribute causes inefficient alignment for 'struct field name'

For example,

struct Struct_test 
{
    uint32_t ch1;
    uint16_t ch2;
    uint32_t ch3;
}
__attribute__( ( packed ) );

warns about the fields ch1 and ch2:

test.c:12:14: warning: packed attribute causes inefficient alignment for 'ch1' [-Wattributes]
   12 |     uint32_t ch1;
      |              ^~~
test.c:13:14: warning: packed attribute causes inefficient alignment for 'ch2' [-Wattributes]
   13 |     uint16_t ch2;
      |              ^~~

As per the manual -Wpacked means: Warn when the packed attribute has no effect on struct layout. But in this case the packed attribute does have an impact on the struct layout as it removes the padding between ch2 and ch3, but still it causes warning.

Edit: Though the warning is listed as associated with: -Wattributes. It doesn't show up if -Wpacked is not given as compile option.

tonyjosi
  • 717
  • 1
  • 9
  • 17
  • The diagnostics tell you what warning option they are associated with: `-Wattributes`, not `-Wpacked`. – John Bollinger Aug 16 '23 at 18:51
  • Although I don't find this documented, I guess `-Wattributes` is being used as a catch-all for diagnostics associated with attributes, that do not otherwise have categories. – John Bollinger Aug 16 '23 at 18:59
  • The warning is misleading as it should be `warning: packed attribute causes inefficient alignment for 'ch1' [-Wpacked]` – 0___________ Aug 16 '23 at 20:04
  • What did gnu/gcc say when you asked? – old_timer Aug 17 '23 at 01:09
  • @JohnBollinger @0___________ though the warning is listed as associated with: `-Wattributes`. It doesn't show up if `-Wpacked` is not given as compile option. – tonyjosi Aug 17 '23 at 03:21

1 Answers1

1

I don't have an ARM CPU to test this on but I think I see the problem. I think if you change your struct to

struct Struct_test 
{
    uint32_t ch1;
    uint32_t ch3;
    uint16_t ch2;
}
__attribute__((aligned(4)))
__attribute__( ( packed ) );

then the issue will go away, unless you make an array of these structs. An array of these packed structs will have alignment issues which may cause undefined behaviour if you attempt to dereference the elements. You have to take care with how you access the data in packed structs with alignment issues. One safe way is to memcpy to a local variable.

In general, it's a good idea to arrange struct elements in a way that conserves space. A simple way to do this is to put the elements in increasing or decreasing order of size.

Simon Goater
  • 759
  • 1
  • 1
  • 7
  • Changing to the suggested struct definition won't work as now all 3 fields are already byte aligned and it will generate 3 warnings. Also its not always possible to change order of fields in struct definitions, for example in a struct definition representing a IP packet it should always conform to the fields in the standard IP packet in that order. – tonyjosi Aug 17 '23 at 12:38
  • @tonyjosi This seems like a 'solution' to leave the elements in the wire form. However, it is almost always the case that a deserialization routine to another 'unpacked' structure will result in better code. The compiler is going to insert all sorts of gymnastics to deal with the un-aligned data. – artless noise Aug 17 '23 at 13:38
  • @tonyjosi Yes, it appear to byte align the whole struct when packed which seems a bit crazy. Do the warnings go away if you add the aligned attribute? I can't get the same warnings... – Simon Goater Aug 17 '23 at 14:33
  • @SimonGoater Even with aligned attribute the warnings are still there. This is the ARM GCC toolchain that I use: [arm-none-eabi-gcc [(Atmel build: 508) 6.3.1 20170620 (release)](https://ww1.microchip.com/downloads/aemDocuments/documents/DEV/ProductDocuments/SoftwareTools/arm-gnu-toolchain-6.3.1.508-linux.any.x86_64.tar.gz) – tonyjosi Aug 17 '23 at 17:24