Jump to content
  • Advertisement
Sign in to follow this  
bios10h

C++ manual padding for alignment

This topic is 4415 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I have a general c++ question... I'm looking for how to do manual padding. I've searched on google and couldn't find anything so I figured someone here might know. I've seen padding to 4 bytes done like this: totalSize = (totalSize + 0x3) & ~0x3; But I'd like to know if that can be generalized? If I want to pad to the next 16 bytes boundary, how can I do it? totalSize = (totalSize + 0x7) & ~0x7; ? totalSize = (totalSize + 0x15) & ~0x15; ? Or the algorithm can't be generalized? Thank you!

Share this post


Link to post
Share on other sites
Advertisement
This really isn't a C++ question; it's an arithmetic question. To "pad" to a multiple of N bytes, you need to find the smallest value X which is (a) divisible by N, and (b) at least as large as your starting value.

We can do this by adding (N-1), dividing by N (discarding the remainder) and then multiplying by N (remember, we discarded the remainder, so the last two steps are not a no-op). That can easily be shown to work:

- the result must be divisible by N, because the last step was a multiplication of an integer by N.
- the result must be at least as large as the starting value, because the remainder that we discard could be *at most* N-1.
- the result will be the smallest satisfying those conditions, because adding N-1 could not increase the result of the remainder-discarding division by more than 1.

Next, when N is a power of 2, the bit-masking happens to be a shortcut for the division and multiplication. Shifting left is equivalent to dividing by 2 and discarding the remainder (which gets shifted out of the number), and shifting right (with zero fill) is equivalent to multiplying by 2, so the division and multiplication steps, for N=2, are equivalent to doing that back and forth shift by one bit. That in turn is equivalent to just zeroing out that bit, which we can do with a bitmask. Similarly, for N=4, we can mask out the low two bits (don't forget the add N-1 step!), three bits for N=8 etc.




We can of course generalize this with a function:


// Pad 'value' to 2^i bytes.

template <int i>
inline void pad(int& value) {
int mask = (1 << i) - 1;
value = (value + mask) & ~mask;
}

// pad 'totalsize' to 4 bytes
pad<2>(totalsize);
// or to 16 bytes
pad<4>(totalsize);

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!