Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are concepts with only a boolean literal value ill-formed, no diagnostic required?

Tags:

I was playing around with C++ concepts and function overloading in a context completely removed from any templates, and stumbled upon this:

struct S {     int mult(int x) requires (true)  { return x; }     int mult(int x) requires (false) { return x * 2; } };  int main() {     std::cout << S{}.mult(5) << std::endl; } 

g++ 11 refuses to compile this snippet because requires-clauses may not be attached to non-template functions.

clang++ 13 is, however, fine with this snippet, but surprisingly spits out 10 instead of the 5 that I expected.

I know that the C++20 standard has only recently come out of the oven, so I completely understand that there are many issues to be worked out regarding concepts.

Disregarding the apparent uselessness of constant literal concepts, my question is: Are programs with requires-clauses which are always false ill-formed, possibly without requiring a diagnostic? Or, perhaps, is what I have not even legal C++ at all, as g++ is saying?

like image 307
tyckesak Avatar asked Jul 16 '21 10:07

tyckesak


2 Answers

These are the two first examples in the "trailing requires-clause" section of the standard:

void f1(int a) requires true;               // error: non-templated function  template<typename T>   auto f2(T a) -> bool requires true;       // OK 

Although examples given in the standard are explicitly non-normative, these make the intent abundantly clear.

Essentially, concepts can only be applied to template functions (so your code is invalid C++), but Boolean literals (e.g., requires true) are perfectly valid.

However, templates whose requirements are never satisfied (whether by a literal false in a required clause or otherwise) seem to be ill-formed, as indicated by this example,

like image 124
n. 1.8e9-where's-my-share m. Avatar answered Sep 29 '22 02:09

n. 1.8e9-where's-my-share m.


Your snippet is not legal C++.

[dcl.decl.general]

4 The optional requires-clause ([temp.pre]) in an init-declarator or member-declarator shall be present only if the declarator declares a templated function ([dcl.fct]). When present after a declarator, the requires-clause is called the trailing requires-clause. [...]

Since there isn't a template in sight (and no room to discuss if the mult overloads are templated functions), your attempt is plain ill-formed. It's a "shall" requirement of a diagnosable rule.

So GCC is correct. Clang is doubly wrong to call a completely unintuitive overload. Though it really went of the rails when it accepted the program to being with.

like image 32
StoryTeller - Unslander Monica Avatar answered Sep 29 '22 03:09

StoryTeller - Unslander Monica