• Advertisement
Sign in to follow this  

C++ manual padding for alignment

This topic is 4144 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