Dun*_*eal 30 c++ compiler-warnings clang++
对于这个简化的测试用例:
#include <map>
class Tester {
int foo;
std::map<int, int> smap;
};
int main() {
Tester test;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我得到以下编译器警告:
$ clang++ -std=c++98 -Weverything test.cc
test.cc:5:24: warning: padding class 'Tester' with 4 bytes to align 'smap' [-Wpadded]
std::map<int, int> smap;
^
Run Code Online (Sandbox Code Playgroud)
任何人都可以解释这个警告意味着什么,以及我应该如何解决它?
Tri*_*dle 25
这里没有真正的问题.在C和C++中,允许编译器在struct成员之后插入填充以提供更好的对齐,从而允许更快的内存访问.在这种情况下,它似乎决定smap放在8字节对齐上.由于int几乎肯定是四个字节,警告告诉您结构中间有四个字节的浪费空间.
如果结构中有更多成员,那么您可以尝试的一件事就是切换定义的顺序.例如,如果您Tester有成员:
struct Tester {
int foo;
std::map<int, int> smap;
int bar;
};
Run Code Online (Sandbox Code Playgroud)
那么将两个整体放在一起以优化对齐并避免浪费空间是有意义的.但是,在这种情况下,您只有两个成员,如果您切换它们,那么编译器可能仍然会在结构的末尾添加四个字节的填充,以便Tester在放入数组时优化s 的对齐.
我假设你在64位系统上编译它.
在64位系统上,指针是8个字节.编译器会将结构成员与自然边界对齐,因此8字节指针将从结构中的偏移量开始,该结构是8字节的倍数.
由于int只有四个字节,编译器在之后插入了4个字节的"填充" foo,因此它smap位于一个8字节的边界上.
编辑:虽然smap不是指针,但是a std::map,同样的逻辑适用.我不确定对象对齐的确切规则是什么,但同样的事情正在发生.
该怎么办?没有.你的代码非常好,编译器只是让你知道这已经发生了.绝对没有什么可担心的. -Weverything意味着打开每一个可能的警告,这对于大多数编辑来说可能都是过多的.