ronald_s56
ronald_s56

Reputation: 321

Avoiding overflow boost container

I was looking through some of boost container memory pool code and came across the following which I do not understand, complete source .cpp .h

//Limit max value
std::size_t blocks_per_chunk
    = boost::container::dtl::min_value(max_blocks_per_chunk, next_blocks_per_chunk);
//Avoid overflow
blocks_per_chunk
    = boost::container::dtl::min_value(blocks_per_chunk, std::size_t(-1)/pool_block);

Specifically I do not understand how the second line of code "avoids overflow". blocks_per_chunk is already set to be the minimum of next and max_blocks_per_chunk. So this should already be in a valid range.

What does dividing -1 by pool_block do in this situation?

Upvotes: 1

Views: 67

Answers (1)

TypeIA
TypeIA

Reputation: 17258

Note that std::size_t(-1) / pool_block is the largest std::size_t value which, when multiplied by pool_block, will not overflow a std::size_t. (Because std::size_t is unsigned, and because of how signed-to-unsigned integer conversions work, std::size_t(-1) is the largest representable std::size_t value, i.e., equivalent to std::numeric_limits<std::size_t>::max() but a little shorter to type.)

I suspect the intent is to restrict blocks_per_chunk to values that won't cause overflows in subsequent math operations using this variable. Indeed, the following code comes right after:

//Minimum block size is at least max_align, so all pools allocate sizes that are multiple of max_align,
//meaning that all blocks are max_align-aligned.
char *p = static_cast<char *>(block_slist_base_t::allocate(blocks_per_chunk*pool_block, mr));

Here, blocks_per_chunk * pool_block would overflow if blocks_per_chunk > std::size_t(-1) / pool_block.

Upvotes: 3

Related Questions