Should constexpr => noexcept?

299 views
Skip to first unread message

Cassio Neri

unread,
Sep 17, 2013, 6:27:13 AM9/17/13
to std-dis...@isocpp.org
Hi,

Quoting n3690 (C++14) [expr.const] 5.19/2

A conditional-expression e is a core constant expression unless the
evaluation of e, following the rules of the abstract machine (1.9), would
evaluate one of the following expressions:
[...]
— a throw-expression (15.1).

Therefore, a constexpr function cannot throw. I couldn't find anything that
says a constexpr function is implicitly declared noexcept. Shouldn't it be
the case?

One selling point of noexcept is that it allows the compiler to generate
faster code. So we could have that for all constexpr functions.

A possibly reason for not doing making constexpr => noexcept is the recent
history of constexrp => const in C++11 which is no longer the case in C++14.
(and this will break code). However, since noexcept is not part of the
signature (correct me if I'm wrong) the consquences of, if one day,
constexpr functions are allowed to throw seem less dramatic (it could still
break code).

Your thoughts?

Cassio.

Gabriel Dos Reis

unread,
Sep 17, 2013, 7:14:57 AM9/17/13
to std-dis...@isocpp.org
Cassio Neri <cassi...@gmail.com> writes:

| Hi,
|
| Quoting n3690 (C++14) [expr.const] 5.19/2
|
| A conditional-expression e is a core constant expression unless the
| evaluation of e, following the rules of the abstract machine (1.9), would
| evaluate one of the following expressions:
| [...]
| — a throw-expression (15.1).
|
| Therefore, a constexpr function cannot throw.

That is not correct.

A call to a constexpr function cannot result in an exception if the call
appears in a constexpr context. Otherwise, it is perfectively fine.

| I couldn't find anything that
| says a constexpr function is implicitly declared noexcept. Shouldn't it be
| the case?

This was indeed considered, but abandonned as, in practice, it would
prevent programmers from using 'checking expressions'.

| One selling point of noexcept is that it allows the compiler to generate
| faster code. So we could have that for all constexpr functions.
|
| A possibly reason for not doing making constexpr => noexcept is the recent
| history of constexrp => const in C++11 which is no longer the case in C++14.
| (and this will break code). However, since noexcept is not part of the
| signature (correct me if I'm wrong) the consquences of, if one day,
| constexpr functions are allowed to throw seem less dramatic (it could still
| break code).
|
| Your thoughts?

try:

#include <stdexcept>

constexpr int check(int x) {
return x > 0 ? x : std::domain_error("non-positive value");
}

int main() {
enum E { e = check(1) };
return e;
}

-- Gaby

Daniel Krügler

unread,
Sep 17, 2013, 7:30:18 AM9/17/13
to std-dis...@isocpp.org

Hi,

Quoting n3690 (C++14) [expr.const] 5.19/2

A conditional-expression e is a core constant expression unless the
evaluation of e, following the rules of the abstract machine (1.9), would
evaluate one of the following expressions:
[...]
— a throw-expression (15.1).

Therefore, a constexpr function cannot throw. I couldn't find anything that
says a constexpr function is implicitly declared noexcept. Shouldn't it be
the case?

and the language was intentionally left in the way to allow exceptions in constexpr functions.
 
One selling point of noexcept is that it allows the compiler to generate
faster code. So we could have that for all constexpr functions.

This can still be the case, even if the language allows exceptions in constexpr functions.
 
A possibly reason for not doing making constexpr => noexcept is the recent
history of constexrp => const in C++11 which is no longer the case in C++14.

No, this change was not related to that in any way.
 
(and this will break code). However, since noexcept is not part of the
signature (correct me if I'm wrong) the consquences of, if one day,
constexpr functions are allowed to throw seem less dramatic (it could still
break code).

Your thoughts?

I'm strongly opposed to such a change, because it would severely constrain functions that are very reasonable condidates for constexpr, such as:

constexpr const_reference at(size_type n) const;

from std::array. Please let's keep things different *that* are different: You would constrain all narrow functions - such as a compile-time version of strlen - to either give some artificial return values if the pre-conditions are violated or you would enforce them to special error handling strategies.

- Daniel

Cassio Neri

unread,
Sep 17, 2013, 8:47:41 AM9/17/13
to std-dis...@isocpp.org, g...@axiomatics.org


On Tuesday, September 17, 2013 12:14:57 PM UTC+1, Gabriel Dos Reis wrote:
    #include <stdexcept>

    constexpr int check(int x) {
      return x > 0 ? x : std::domain_error("non-positive value");
    }

    int main() {
       enum E { e = check(1) };
       return e;
    }
I see! Thanks for the illuminating example.

 On Tuesday, September 17, 2013 12:30:18 PM UTC+1, Daniel Krügler wrote:

and the language was intentionally left in the way to allow exceptions in constexpr functions.
- Daniel

Thanks for the link.

Reply all
Reply to author
Forward
0 new messages