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


The standard on <em>constexpr functions</em> states under point 5 of [decl.constexpr]:


<em>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.</em>


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 <em>extremely bizarre</em>, 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?

<hr />

Presumably the following are fine?

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

The rationale for this rule is that there should be <em>at least one</em> 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 <em>all</em> paths through this function will end in an expression that is not a <em>core constant expression</em>.

A compiler would have to evaluate <em>all</em> 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 <em>ill-formed-no-diagnostic-required</em>, 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 <em>core-constant-expression</em>.

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 <em>"... if no argument values exist such that ..."</em> 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.



  • What's the difference between instanceId and getIdToken
  • download url is getting as com.google.android.gms.tasks.zzu@441942b : Firebase Storage [Kotlin] [Sol
  • What are the purpose of trunk/branch/tags in svn? [duplicate]
  • Set custom dialog once into activity
  • gnuplot - plot different blocks with different color
  • Got Exception Error “Exception in thread Thread-1 (most likely raised during interpreter shutdown)”
  • Antialiasing on OpenGL ES 2.0
  • select multiple elements with group by in spark.sql
  • How to implement 'if' in Gherkin
  • Lazy Evaluation - Space Leak
  • How to bend a cylinder in three.js?
  • Unicode File IO in Codename One
  • Bootstrap 3 Validation
  • apache zeppelin is started but there is connection error in localhost:8080
  • MySQL - Filter records which date is biggest
  • Decimal to ASCII Conversion [closed]
  • plot dirac function in matlab
  • How do you run a synchronous timer in C#?
  • Yii Bootstrap not loading JS files
  • How to create OLE Automation to be used with ClearExplorer
  • Validating my form with Jquery
  • Showing image on a acro text field position
  • Error handeling in antlr 3.0
  • DataTables move rows between tables
  • reshape/remould data frame to create normalized bar chart and pie chart
  • Google App Engine Datastore: Dealing with eventual consistency
  • Sign a Pdf using custom digital signature in Java
  • Cross compile glibc for arm, got undefined reference to some unwind functions
  • Why does Rails 3 think xE2x80x89 means â x80 x89
  • Accessing Arguments, Workflow Variables from custom activities
  • Angular FormGroup won't update it's value immediately after patchValue or setValue
  • How do I use TagLib-Sharp to write custom (PRIV) ID3 frames?
  • CAS 4 - Not able to retrieve the LDAP groups after successful authentication
  • ReferenceError: TextEncoder is not defined
  • JavaScript RegExp Replace