Skip to content

Conversation

@eadf
Copy link
Contributor

@eadf eadf commented Jul 11, 2025

bits_per_block() and bytes_per_block() now compiles into usize literals: the ultimate inline.

src/lib.rs Outdated
}
/// to store those bits. (Using the classic ceiling division formula: ⌈n / b⌉ = ⌊(n + b - 1) / b⌋)
const fn blocks_required<T>(num_bits: usize) -> usize {
(num_bits + bits_per_block::<T>() - 1) / bits_per_block::<T>()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A problem with this (more on 32 than 64 bit) is that it can overflow, even with a valid (and on 32 bit, very plausible) size. Even worse, in release mode, it won't cause a panic -- something weird will happen, but I'm not quite sure what in this context!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, i see.
We could write it as num_bits / bits_per_block::<T>() + (remainder != 0 as usize) instead, and still be branchless (unless as adds some under the hood).

And yes, bool as usize is idiomatic, safe, rust code.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm allergic to as, but usize::from probably works and would be fine with me!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if replacing an if branch with a, potentially non-inlined, method call is any improvement:

fn blocks_required<T>(num_bits: usize) -> usize {
    num_bits / bits_per_block::<T>() + usize::from(num_bits % bits_per_block::<T>() != 0)
}

Just checked with godbolt: with "-C opt-level=3" both as and usize::from() compiles down to the same one-single-OP code.

Copy link
Collaborator

@ratmice ratmice Jul 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It definitely looks to me like the from impl just calls as in an #[inline(always)] function.
https://doc.rust-lang.org/src/core/convert/num.rs.html#76-79

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My problem with as is that it has surprising use edge cases, which are double dangerous if types are later changed. It works well until it doesn't!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, as can be dicey. Specially on machines where usize != u64, but once wrapped inside std::from() it's the problem of the Rust maintainers.
For this particular conversion: bool -> usize, the op is safe even if usize is anu8.

@ltratt
Copy link
Member

ltratt commented Jul 12, 2025

We're having some problems with github at our end, so this might take a little while to merge in. Don't worry, it will!

@ltratt ltratt disabled auto-merge July 13, 2025 06:59
@ltratt
Copy link
Member

ltratt commented Jul 13, 2025

Please can you force push an update to this branch? Hopefully that will kick our CI back into life.

Made bits_per_block(), bytes_per_block() and block_offset() const fn.
@ltratt ltratt added this pull request to the merge queue Jul 13, 2025
Merged via the queue into softdevteam:master with commit c9c5577 Jul 13, 2025
2 checks passed
@eadf eadf deleted the const_fn branch July 19, 2025 16:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants