What does [decl.constexpr].5 mean exactly?

谁说胖子不能爱 提交于 2020-06-16 02:26:30

问题


The standard on constexpr functions states under point 5 of [decl.constexpr]:

For a non-template, non-defaulted constexpr function or a non-template, non-defaulted, non-inheriting constexpr constructor, if no argument values exist such that an invocation of the function or constructor could be an evaluated subexpression of a core constant expression (5.19), the program is ill-formed; no diagnostic required.

It goes on to give the following example for this:

constexpr int f(bool b){ return b ? throw 0 : 0; }  // OK
constexpr int f() { return f(true); }               // ill-formed, no diagnostic required

What I take from this is that functions with empty argument lists are no-diagnostic ill-formed. This strikes me as extremely bizarre, such that I suspect that my understanding is incorrect. For instance, would this also be ill-formed:

constexpr int g() { return 0; }       // ill-formed?

If so, what is the rationale behind this, and if not what does the qualification mean / when does a constexpr function become ill-formed?


Presumably the following are fine?

constexpr int h(int x) { return x; }  // presumably fine?
constexpr int l = h(42);              // also fine

回答1:


The rationale for this rule is that there should be at least one context where the function can be evaluated in a constexpr context. e.g. given:

constexpr int f(bool b){ return b ? throw 0 : 0; }  // OK
constexpr int f() { return f(true); }               // ill-formed, no diagnostic required

There is no way to invoke f() in a constexpr context, since all paths through this function will end in an expression that is not a core constant expression.

A compiler would have to evaluate all possible calls to see if there is any way the function is usable in a constexpr context. This is not easily diagnosable in general, so the language says it's ill-formed-no-diagnostic-required, i.e. you've done something wrong, but the compiler can't diagnose it.

Note that if the zero argument overload of f was the following:

constexpr int f() { return f(false); }   // ok

that would be perfectly fine, since the evaluation ends in a core-constant-expression.

Similarly, this function:

constexpr int g() { return 0; }      // ok

as well as this one:

constexpr int h(int x) { return x; }  // ok
constexpr int l = h(42);              // ok

are fine, since g and h can be invoked in a constexpr context.

The wording of "... if no argument values exist such that ..." might be confusing, as you've asked about the well-formedness of g. But g can be invoked with zero arguments, or in other words, with a void argument, so it's fine.



来源:https://stackoverflow.com/questions/62327672/what-does-decl-constexpr-5-mean-exactly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!