Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are `inline` and `noexcept` redundant in a consteval context?

I am working with some code in which constexpr functions are used which I currently refactor to be consteval whenever possible.

inline constexpr auto example() noexcept { /*...*/ }

As I understand it, the inline keyword above is already redundant in the constexpr function.

As far as I understand it, the noexcept keywords are redundant for consteval functions, because as I understand it consteval has to be evaluated at compile time, and hence implies noexcept. Is this true or might there be something I currently do not consider (like constexpr exceptions)?

consteval auto example() { /*...*/ }
like image 263
mutableVoid Avatar asked Feb 27 '20 15:02

mutableVoid


People also ask

Are constexpr variables inline?

Also, note that constexpr variables are inline implicitly, so there's no need to use constexpr inline myVar = 10; . Why can it simplify the code? For example, a lot of header only libraries can limit the number of hacks (like using inline functions or templates) and just use inline variables.

Are constexpr functions inline?

A constexpr specifier used in a function or static data member (since C++17) declaration implies inline .


1 Answers

inline is redundant because: [dcl.constexpr]/1:

A function or static data member declared with the constexpr or consteval specifier is implicitly an inline function or variable ([dcl.inline]).


noexcept is somewhat more interesting. It is true that an attempt to throw an exception (whether via throw, dynamic_cast, or typeid) is not allowed during constant evaluation time ([expr.const]/5.24). And since a consteval function is only evaluated during constant evaluation time, the noexcept has minimal benefit - an exception will certainly never escape this scope. And, moreover, you can't even have a function pointer to these functions leak to runtime either. There really is no mechanism I can think of for which this would be relevant.

However, perhaps at some point in the future, might we be allowed to have exceptions during constant evaluation? And if we go there, would it become important to know about noexcept-ness in that world? An exception that leaks out of a constant evaluation context would likely have to mean a compile error, so might you have algorithms that make different choices based on the noexcept-ness of a consteval function?

That said, I'd skip the noexcept. It certainly has no benefit now, and it may not even have benefit in the future. And if I end up being wrong then... I'm sorry.

Although really, as T.C. points out, it's not that simple:

consteval int current() { return 1; }
void f(int, int = current()) noexcept;

What's noexcept(f(1))? As written, it's false. And that's pretty weird right, since this the expression f(1) definitely isn't going to throw. So maybe you should write noexcept. Although since again it definitely can't throw, maybe the language should make consteval functions noexcept by default. Although if we do that, and do eventually add exceptions during constant evaluation time... now we're back to lying again since that's something we won't be able to claw back.

like image 65
Barry Avatar answered Oct 19 '22 15:10

Barry