Fred
Fred

Reputation: 457

Optional throw in constexpr?

I was researching how to implement a compile time strlen for a toy project in this repo https://github.com/elbeno/constexpr when I noticed an unusual pattern of throws in some of the code. It seemingly does nothing, why would you do this?

namespace err {
    extern const char * strlen_runtime_error;
}
constexpr int strlen(const char * str) {
    return true ? constexpr_func() : throw strlen_runtime_error;
}

I got curious if it has any use what so ever but couldn’t find anything useful on my own. The extern err is undefined.

Upvotes: 1

Views: 89

Answers (1)

Acorn
Acorn

Reputation: 26166

It seems it is trying to enforce the function being used only in compile time, according to this comment in another of the functions of the library:

// convenience function for inferring the string size and ensuring no
// accidental runtime encryption
template <uint64_t S, size_t N>
constexpr encrypted_string<S, N> make_encrypted_string(const char(&s)[N])
{
  return true ? encrypted_string<S, N>(s) :
    throw err::strenc_runtime_error;
}

However, as you point out, it is not doing anything here. Typically, that trick with the ternary operator in constexpr functions is used to trigger compile-time errors given a condition -- not to ensure all calls to the function are constant expressions. See constexpr error at compile-time, but no overhead at run-time for an explanation of that pattern.

If you need to ensure that the result was found out during compile time, you can easily assign the result to a constexpr variable:

constexpr int result = strlen("asd");

Upvotes: 1

Related Questions