C++ “带有 4 个字节的填充类 'Tester'”警告是什么意思?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20184259/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:57:48  来源:igfitidea点击:

What does the "padding class 'Tester' with 4 bytes" warning mean?

c++compiler-warningsclang++

提问by Dun Peal

For this simplified test case:

对于这个简化的测试用例:

#include <map>

class Tester {
    int foo;
    std::map<int, int> smap;
};

int main() {
    Tester test; 
    return 0;
}

I get the following compiler warning:

我收到以下编译器警告:

$ 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;
                       ^

Can anyone explain what this warning means, and how I should address it?

谁能解释这个警告的含义,以及我应该如何解决它?

采纳答案by Tristan Brindle

There's no real problem here. In C and C++, the compiler is allowed to insert padding after struct members to provide better alignment, and thus allow faster memory access. In this case, it looks like has decided to place smapon an 8-byte alignment. Since an intis almost certainly four bytes, the warning is telling you that there are four bytes of wasted space in the middle of the struct.

这里没有真正的问题。在 C 和 C++ 中,允许编译器在结构成员之后插入填充以提供更好的对齐,从而允许更快的内存访问。在这种情况下,看起来已经决定放置smap在 8 字节对齐上。由于 anint几乎肯定是四个字节,因此警告告诉您结构中间有四个字节的空间浪费。

If there were more members of the struct, then one thing you could try would be to switch the order of the definitions. For example, if your Testerhad members:

如果结构中有更多成员,那么您可以尝试的一件事是切换定义的顺序。例如,如果您Tester有成员:

 struct Tester {
     int foo;
     std::map<int, int> smap;
     int bar;
 };

then it would make sense to place the two ints next to each other to optimise alignment and avoid wasted space. However, in this case, you only have two members, and if you switch them around then the compiler will probably still add four bytes of padding to the end of the struct in order to optimise the alignment of Testers when placed inside an array.

那么将两个整数放在一起以优化对齐并避免浪费空间是有意义的。但是,在这种情况下,您只有两个成员,如果您切换它们,那么编译器可能仍会在结构的末尾添加四个字节的填充,以便Tester在放置在数组中时优化s的对齐方式。

回答by Jonathon Reinhart

I'm assuming you're compiling this on a 64-bit system.

我假设您是在 64 位系统上编译它。

On 64-bit systems, pointers are 8 bytes. Compilers will align structure members to natural boundaries, so an 8-byte pointer will start at an offset in a structure that is a multiple of 8 bytes.

在 64 位系统上,指针是 8 个字节。编译器会将结构成员与自然边界对齐,因此 8 字节指针将从结构中的偏移量开始,该偏移量是 8 字节的倍数。

Since intis only four bytes, the compiler inserted 4 bytes of "padding" after foo, so that smapis on an 8-byte boundary.

由于int只有四个字节,编译器在 之后插入了 4 个字节的“填充” foo,因此smap在 8 字节边界上。

Edit: While smapis not a pointer, but a std::map, the same logic applies. I'm not sure what the exact rules for alignment of objects are, but the same thing is happening.

编辑: Whilesmap不是指针,而是 a std::map,同样的逻辑适用。我不确定对象对齐的确切规则是什么,但同样的事情正在发生。

What to do? Nothing. Your code is perfectly fine, the compiler is just letting you know that this has taken place. There's absolutely nothing to worry about. -Weverythingmeans turn on every possible warning, which is probably excessive for most all compilations.

该怎么办?没有。你的代码非常好,编译器只是让你知道这已经发生了。完全没有什么可担心的。 -Weverything意味着打开所有可能的警告,这对于大多数编译来说可能是过度的。

回答by Ivanovic

Your compiler on your sytsem chose to give pointers on your 64bit system 8 bytes, int in the struct has 4 bytes. Similar problems/warnings are occurring to me a lot those days working with older code examples so I had to dig deeper.

您系统上的编译器选择在您的 64 位系统上提供指针 8 bytes,结构中的 int 具有4 bytes. 在使用旧代码示例的那些日子里,我经常遇到类似的问题/警告,所以我不得不深入挖掘。

To make it short, intwas defined in the 60's with no 64 bit system, no Gigabytes of storage nor GB of ram in mind.

简而言之,它int是在 60 年代定义的,没有 64 位系统,没有千兆字节的存储空间,也没有考虑 GB 的内存。

To solve your error message use size_t(size type)instead of intwhen necessary - in your case with the map stlsince it is programmed to run on multiple different systems.

要解决您的错误消息,请使用size_t(大小类型)而不是int在必要时 - 在您的情况下使用map stl,因为它被编程为在多个不同的系统上运行。

With size_tyour compiler can choose itself what byte size it needs if it compiles on a 32 bit system or a 64 bit system or arm or what ever and the message is gone and you won't even have to modify your code no matter what system you may compile your code for in the future.

随着size_t你的编译器可以选择自己需要什么样的字节大小,如果它编译在32位系统还是64位系统上或手臂或什么都和消息是走了,你甚至不会有问题,任何什么系统,您修改代码将来可能会编译您的代码。