Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

expression in requirement-seq no longer IFNDR due to DR2392 #6055

Closed
sunmy2019 opened this issue Jan 22, 2023 · 3 comments · Fixed by #6062
Closed

expression in requirement-seq no longer IFNDR due to DR2392 #6055

sunmy2019 opened this issue Jan 22, 2023 · 3 comments · Fixed by #6062

Comments

@sunmy2019
Copy link

https://eel.is/c++draft/expr.prim.req.general#5 has this example

template<typename T> concept C =
requires {
  new int[-(int)sizeof(T)];     // ill-formed, no diagnostic required
};

This is previously IFNDR.

But with DR2392 accepted in Nov. 2022, for every T, this expression is well-formed whenever it is in an unevaluated context. We can even write new int[-1] in the requirement-seq, the program is well-formed.

https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2392
https://cplusplus.github.io/CWG/issues/2392.html

@sunmy2019
Copy link
Author

sunmy2019 commented Jan 22, 2023

I got another question.

In the standard, the following %1 and %2 are unevaluated operands

template <typename T>
concept C = /* %1 */ true;

template <typename T>
concept CC = requires {
    requires /* %2 */ C<T>;
};

%1 is defined here: https://eel.is/c++draft/temp.concept#6
%2 is defined here: https://eel.is/c++draft/expr.prim.req#general-2

But clearly, they are evaluated and must evaluate to be true at compile time. (edited)

IMO, an unevaluated expression should be something we did not check its value, something like

  // DR 2392
  template<class T = void> constexpr int f() { T t; return 1; }
  using _ = decltype(new int[f()]);

But we cannot write

template <typename T>
concept C = foo();

So what's wrong here? Do I misinterpret anything?

@JohelEGP
Copy link
Contributor

JohelEGP commented Jan 23, 2023

But clearly, they are evaluated and must evaluate to be true at compile time.

They are evaluated when the naming a concept specialization outside unevaluated operands, and need not evaluate to true.

@frederick-vs-ja
Copy link
Contributor

I think the example is not definitely correct even before CWG2392 - since some implementation may allow large object types of size equal to UINT_MAX + size_t(1), in which case -(int)sizeof(T) is 0 if T is such a type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants