我有以下无害的代码:
void myFunc(){
struct stance {
long double interval;
QString name;
};
// [...]
}
当我在Ubuntu 18.04上使用标准版本的gcc构建此文件时,会收到如下警告:
MySource.cpp:12:警告:“姿态”的填充大小为8个字节, 对齐边界(-wpipped)
我知道出现此警告是因为编译器需要将我的结构的填充调整为我可能无法预期的程度,并且足以警告用户有关此的警告。
但是,我试图构建一个没有警告的版本,所以问题是,我如何以一种符合标准的方式在我的代码中明确指出编译器不需要发出此警告?< / strong>
很明显,我不想在构建脚本中禁止显示警告,也不想使用#pragma或类似方法。我想更改此结构的代码,以便我的对齐期望是明确的,并且与编译器想要执行的操作匹配,因此不需要显示警告。
答案 0 :(得分:3)
只需禁用警告(或者-好的,不要启用它,我不知道包含它的任何警告集,例如-Wall
或-Wextra
)。 -Wpadded
并非总是启用的,除非您希望始终手动明确指定必要的填充。
-Wpapped
警告填充是否包含在结构中,以对齐结构的元素或对齐整个结构。 有时发生这种情况时,可以重新排列结构的字段以减少填充,从而使结构更小。
(添加了重点)
这是不可能的一种情况。 long double
是10字节,需要16字节对齐(在x86 Linux上为4); QString
实际上是一个指针,因此它需要8字节对齐(在32位Linux上为4)。您可以根据需要交换它们,但是如果要保持自然对齐(从而获得最佳性能),则将获得6 + 8字节的填充或8 + 6字节的填充。
通常,添加填充不是问题,它总是会发生,并且在不可避免的情况下会出现诸如此类的情况。将其保持在最低限度的一般规则是按照减少对齐要求的顺序放置元素,但同样,不能总是避免这样做。
如上所述,唯一的选择(保持良好的对齐)是使填充显式显示,但这没有多大意义(除非您正在设计文件格式或其他内容,并且希望使所有内容显式显示,但是在那种情况下)如果您不使用QString
并将其压缩为1个字节)。
struct stance {
long double interval;
char unused0[6];
QString name;
char unused1[8];
};
答案 1 :(得分:0)
我想更改此结构的代码,以便我的对齐期望是明确的
您似乎想要alignof
operator并将其与alignas
specifier一起使用。因此,您至少需要C ++ 11,并且可能需要std::alignment_of