Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 751
Dun Peal Avatar asked Nov 25 '13 03:11

Dun Peal


2 Answers

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 smap on an 8-byte alignment. Since an int is almost certainly four bytes, the warning is telling you that there are four bytes of wasted space in the middle of the struct.

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 Tester had members:

 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.

like image 133
Tristan Brindle Avatar answered Oct 08 '22 10:10

Tristan Brindle


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

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.

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

Edit: While smap is 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.

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. -Weverything means turn on every possible warning, which is probably excessive for most all compilations.

like image 44
Jonathon Reinhart Avatar answered Oct 08 '22 10:10

Jonathon Reinhart