0

I have some code which needs to check if a bit in a bit field is set. I've been impressed with how optimized std::bitset.count compiles down, so thought this would be a good use of it as well. I'm surprised that when I use bitset.test, the compiler is still checking for exceptions, even when I add noexcept.

I have other checks to ensure that I won't test a bit which is out of range. Is there anything else I can do to optimize this code?

bool bitset_test(int n, size_t m) noexcept {
    // The caller already verifies m is within range
    return std::bitset<64>( n ).test( m );
}

Compiled output: https://godbolt.org/g/uRggXD

Brad
  • 5,492
  • 23
  • 34
  • 1
    The compiler still needs to call `std::terminate` if `.test(m)` throws. – Justin Nov 10 '17 at 22:04
  • `noexcept` does not mean that the function is guaranteed to go without exceptions. It just means that you claim that there wont be an exception and if there is one you get screwed – 463035818_is_not_an_ai Nov 10 '17 at 22:05

1 Answers1

3

Is there anything else I can do to optimize this code?

Yes! Just like other containers, std::bitset has a function to get a specific bit with and without bounds checking. test is the bounds checking function, which throws.

But if you have other tests to make sure that m is not too high, then you can use std::bitset's operator[], which doesn't have any exception handling in the resulting assembly, because it assumes that you are passing a correct value:

bool bitset_test(int n, size_t m) noexcept {
    return std::bitset<64>(n)[m];
}

As others have mentioned, the reason why the compiler still generates exceptions in the resulting assembly is because the compiler still has to call std::terminate if an exception is thrown, so it can't just ignore the exception.

Rakete1111
  • 47,013
  • 16
  • 123
  • 162
  • Ugh, I'm so disappointed in myself that I didn't consider that :) Thank you for pointing it out! – Brad Nov 10 '17 at 22:40