Hacker News new | ask | show | jobs
by mxmlnkn 1043 days ago
I wanted to reply that your point 3 should already be possible with C++ constexpr functions because it doesn't allow undefined behavior. But I it seems I was wrong about that or maybe I'm doing it wrong:

    [[nodiscard]] constexpr uint64_t
    getBits( uint8_t nBits )
    {
        return BITBUFFER >> ( 64 - nBits ) & ( ( 1ULL << nBits ) - 1U );
    }
 
    int main()
    {
        std::cerr << getBits( 0 ) << "\n";
        std::cerr << getBits( 1 ) << "\n";
        return 0;
    }
The first output will print a random number, 140728069214376 in my case, while the second line will always print 1. However, when I put the ( ( 1ULL << nBits ) - 1U ) part into a separate function and print the values for that, then getBits( 0 ) suddenly always returns 0 as if the compiler understands suddenly that it will and with 0.

    template<uint8_t nBits>
    [[nodiscard]] constexpr uint64_t
    getBits2()
    {
        return BITBUFFER >> ( 64 - nBits ) & ( ( 1ULL << nBits ) - 1U );
    }
In this case, the compiler will only print a warning when trying to call it with getBits2<0>. And here I kinda thought that constexpr would lead to errors on undefined behavior, partly because it always complains about uninitialized std::array local variables being an error. That seems inconsistent to me. Well, I guess that's what -Werror is for ...

Compiled with -std=c++17 and clang 16.0.0 on godbolt: https://godbolt.org/z/qxxWW93Tx

1 comments

Unfortunately constexpr doesn't imply constant evaluation. Your function can still potentially be executed at runtime.

If you use the result in an expression that requires a constant (an array bound, a non-type template parameter, a static_assert, or, in c++20, to initialize a constinit variable), then that will force constant evaluation and you'll see the error.

Having said that, compilers have bugs (or simply not fully implemented features), so it is certainly possible that both GCC and clang will fail to correctly catch constant time evaluation UB in some circumstances.

Ah thanks, I was not aware that these compile-time checks are only done when it is evaluated in a compile-time evaluating context.

To add to your list, using C++20 consteval instead of constexpr also triggers the error.