arm-none-eabi-gcc:packed 属性导致对齐效率低下

arm-none-eabi-gcc: packed attribute causes inefficient alignment

提问人:tonyjosi 提问时间:8/17/2023 最后编辑:tonyjosi 更新时间:8/17/2023 访问量:83

问:

将选项添加到 arm-none-eabi-gcc combiler 时,它会发出以下警告:-Wpacked

警告:打包属性导致“结构字段名称”的对齐效率低下

例如

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

警告字段 ch1 和 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;
      |              ^~~

根据手册的意思是:当 packed 属性对结构布局没有影响时发出警告。但在这种情况下,packed 属性确实会对结构布局产生影响,因为它删除了 ch2 和 ch3 之间的填充,但仍然会引起警告。-Wpacked

编辑:尽管警告被列为与以下项相关联。如果未作为编译选项给出,则不会显示。-Wattributes-Wpacked

c arm-none-eabi-gcc

评论

0赞 John Bollinger 8/17/2023
诊断程序会告诉您它们与哪个警告选项相关联: ,而不是 。-Wattributes-Wpacked
0赞 John Bollinger 8/17/2023
虽然我没有发现这有记录,但我想它被用作与属性相关的诊断的包罗万象,这些属性没有其他类别。-Wattributes
0赞 0___________ 8/17/2023
该警告应具有误导性warning: packed attribute causes inefficient alignment for 'ch1' [-Wpacked]
0赞 old_timer 8/17/2023
当你问gnu/gcc时,他们说了什么?
0赞 tonyjosi 8/17/2023
@JohnBollinger @0___________ 尽管警告被列为与以下内容相关联: 。如果未作为编译选项给出,则不会显示。-Wattributes-Wpacked

答:

1赞 Simon Goater 8/17/2023 #1

我没有 ARM CPU 来测试它,但我想我看到了问题所在。我想如果你把你的结构改成

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

那么问题就会消失,除非你创建一个这些结构的数组。这些打包结构的数组将存在对齐问题,如果尝试取消引用元素,可能会导致未定义的行为。您必须注意如何访问具有对齐问题的打包结构中的数据。一种安全的方法是对局部变量进行 memcpy。

通常,以节省空间的方式排列结构元素是个好主意。执行此操作的一种简单方法是将元素按大小递增或递减的顺序排列。

评论

0赞 tonyjosi 8/17/2023
更改为建议的结构定义将不起作用,因为现在所有 3 个字段都已经字节对齐,并且会生成 3 个警告。此外,并非总是可以更改结构定义中字段的顺序,例如,在表示 IP 数据包的结构定义中,它应始终按该顺序符合标准 IP 数据包中的字段。
0赞 artless noise 8/17/2023
@tonyjosi 这似乎是将元素保留在线形中的“解决方案”。但是,几乎总是这样,将反序列化例程转换为另一个“解包”结构将产生更好的代码。编译器将插入各种体操来处理未对齐的数据。
0赞 Simon Goater 8/17/2023
@tonyjosi 是的,打包时它似乎对整个结构进行字节对齐,这似乎有点疯狂。如果添加对齐属性,警告是否会消失?我无法获得相同的警告......
0赞 tonyjosi 8/18/2023
@SimonGoater 即使使用对齐的属性,警告仍然存在。这是我使用的 ARM GCC 工具链: arm-none-eabi-gcc [(Atmel build: 508) 6.3.1 20170620 (release)