Date: Wed, 29 Jan 2025 23:57:52 +0100
hello,
I am writing again about the topic of:
https://lists.isocpp.org/std-discussion/2025/01/2783.php
and
https://lists.isocpp.org/std-discussion/2025/01/2787.php
for which I have got no answer.
I may suppose you are intentionally lowering the frequence to answer me
because of I am posting a quite number of questions in these months. That's
ok to me, but I hope you may increase the frequency in case no other
discussions are in place by other users.
I will try again to recap the 3 questions. related to the constraints.
As general idea, I have got that an invalid type/expression leads the
constraint just to fail if it is in immediate-context, otherwise to an
ill-formed program if in non-immediate-context (e.g., in the body of a
lambda expression),
provided that the verification of that type/expression is triggered by the
fact that previous parts of the constraint (in the lexical order, e.g., in
the pieces of a requires expression, or in the combined list of atomic
constraints for a normal form) weren't able to determine already an overall
result for the constraint (e.g., false for an AND combination, or true for
an OR combination),
but also that an invalid type/expression always in place for a templated
entity (i.e., regardless of the instantiation) represents an IFNDR case.
That said, I have reported in
https://lists.isocpp.org/std-discussion/2025/01/2783.php the text
associated to both requires expression ([expr.prim.req.general]-p5) and
atomic constraint ([temp.constr.atomic]-p3 and [temp.res.general]-p(6.4)),
and I have noticed two potential problematic topics when an atomic
constraint is made by a requires expression.
I recall them in the following, and refine/fix details of the discussion.
Before discussing the detail of the first 2 questions, it is important to
highlight that the normal form of the constraints associated to a function,
is built according to rules from [temp.constr.normal], where no 'explosion'
is indicated in case of requires expression, which means that a requires
expression boils down to be an atomic constraint even when it contains
multiple requirements (simple, type, compound, nested:
[expr.prim.req.general]-p1).
A) the first topic is for the case when that requires expression contains a
nested requirement, which therefore contains a constraint-expression, in
turn supposed to contain AND / OR operators, combining further nested
constraints/requirements; let's now suppose that one of these nested ones
contains an invalid type/expression, but also that another
constraint/requirement preceding in the lexical order, allows to provide a
true value for the original requires expression.
If I would exactly apply the text of [temp.constr.atomic]-p3, then it reads
that an invalid type/expression (in immediate context) leads soon the
constraint to be not satisfied, whereas the rules from
[expr.prim.req.general]-p5
postpone the check of invalid type/expression for each contained
requirement only after that previous requirements have already been checked
and successfully verified (true result), and similarly the rules from
[temp.constr.op]-p2/p3
state that the constraints conjunctions and disjunctions are checked one by
one, ignoring the residual ones as soon as a constraint allows to get a
logical overall result.
Please, note that in my original post (2783), I erroneuosly considered a
case with false overall logical result for the requires expression, and
invoked only the rules from [expr.prim.req.general]-p5, but this is not a
conflict because the final result as false is provided by both
[temp.constr.atomic]-p3
and [expr.prim.req.general]-p5.
As highlighted in the second post (2787), I really believe that everything
becomes clear and well consistent if the presence of an invaild
type/expression within a requires expression does not mean that the
requires expression is itself an invalid expression. Indeed, this would
represent a hierarchical separation between the atomic constraint and what
is inside the requires expression.
Please, let me know if this is true, and if in your opinion this is in some
way already clear in the standard for any motivation (e.g., concept of
'immediate context', or anything else).
If the solution is in the definition of 'immediate context', don't you
believe that the standard might state clearly something (similar to
[temp.deduct.general]-p9) about the requirement-body not being part of the
immediate context of an atomic constraint corresponding to the requires
expression ? However, in such case, I would be also afraid of formally
incorrectness about the effect of invalid within the requirements of the
requires-expression (i.e., invalid in a non-immediate context for the
original atomic constraint), and therefore some more note should be added
to clarify that any decision is based on the rules for those requirements.
Otherwise (if none of the previous ones apply), do you believe (as I do)
that the standard may be clarified in [temp.constr.atomic]-p3 when an
atomic constraint is made by a requires expression, and eventually
even in [expr.prim.req.general]-p5
in order to introduce a similar 'hierarchical separation' when one of the
requirements is a nested requirement ? (but I don't know if it was really
intended to have also the second mentioned kind of hierarchy... likely not).
B) the second topic is related to the cases of IFNDR when the invalid
type/expression is always in place; indeed, [expr.prim.req.general]-p5
reads that the IFNDR is there anyway, which means regardless of any
satisfation check is performed or not involving the part containing the
invalid type/expression; on the contrary, [temp.res.general]-p(6.4) reads
that the IFNDR is only effective with the additional condition that no
satisfaction check is performed on the constraint-expression containing the
always-invalid type/expression.
But, what happens if the invalid is in an immediate context, a check is
performed, therefore (based on [temp.constr.atomic]-p3) the constraint is
just not satisfied but no ill-forming is notified by the compiler ?
Is it really wanted to drop the IFNDR just because a check was performed ?
Can I state that if the invalid is inside a requires expression, the IFNDR
remains anyway in place based on [expr.prim.req.general]-p5 ?
Was also here any hierarchical separation intended as discussed for
previous topic ?
Note also that [temp.res.general]-p(6.4) makes no distinction between
immediate and non-immediate contexts, nor between templated and
non-templated entities -> is it really wanted not to have IF for
non-immediate contexts ? Not even for non-templated entities (for them, Note
1 in [expr.prim.req.general]-p5 for requires expressions states IF instead
of IFNDR) ?
Note finally that last part of [expr.prim.req.general]-p5 (after Note 1)
seems not to be specific for immediate or non-immediate contexts, but I do
believe that for non-immediate ones the intended behaviour is IF instead of
IFNDR, isn't it ?
Last topic, with a short question:
C) (which was presented since the post 2783):
In [temp.constr.normal], the example in p1.4) reads that the atomic
constraint-expression 'true' has empty mapping.
The point is that no rule from [temp.constr.normal] exactly states the
possibility to get an empty mapping.
We have part p(1.9) as default case always indicating an identity mapping.
I guess it should be extended to indicate empty mapping when the expression
is constant, that is, not involving any template parameter (you know
for sure the best formal words to say it there).
I don't believe it's fair to consider the definition of this special case
just through the example in p(1.4).
Thank you.
Il giorno gio 16 gen 2025 alle ore 01:15 mauro russo <
ing.russomauro_at_[hidden]> ha scritto:
> I thought about the topics once more.
> (https://lists.isocpp.org/std-discussion/current/2783.php)
>
> Maybe the solution about the potential ambiguity between the rules on
> atomic constraints and the rules on requires-clause, is that a
> requires-clause including invalid type/expression, is not itself an invalid
> expression, as this would mean that an atomic constraint being a
> requires-clause means that the requires-clause is well-formed (valid
> expression) and so only the rules for requires-clause apply.
>
> Please, confirm this is true. However, in such a case, I would suggest to
> add a short note in [temp.constr.atomic]. I am not convinced such a note
> would be a 'tutoring'... but you can choose.
>
> Additionally, I still wonder about the text in [temp.res.general] -
> p(6.4), which appear with a different spirit from [expr.prim.req.general] -
> p5, because in case the always-ill-forming is in an immediate context and
> there is any code triggering the check involving that context, the former
> does not lead to IFNDR (nor to a compilation error triggered by the
> existing check), whereas the latter does it (IFNDR for immediate context,
> and of course compilation error for non-immediate context).
>
> Even my third doubt, that is about the need to specify the generation of
> atomic constraints with empty mapping, still applies.
>
> Please, read previous message (mentioned above) of this thread for the
> complete background.
>
I am writing again about the topic of:
https://lists.isocpp.org/std-discussion/2025/01/2783.php
and
https://lists.isocpp.org/std-discussion/2025/01/2787.php
for which I have got no answer.
I may suppose you are intentionally lowering the frequence to answer me
because of I am posting a quite number of questions in these months. That's
ok to me, but I hope you may increase the frequency in case no other
discussions are in place by other users.
I will try again to recap the 3 questions. related to the constraints.
As general idea, I have got that an invalid type/expression leads the
constraint just to fail if it is in immediate-context, otherwise to an
ill-formed program if in non-immediate-context (e.g., in the body of a
lambda expression),
provided that the verification of that type/expression is triggered by the
fact that previous parts of the constraint (in the lexical order, e.g., in
the pieces of a requires expression, or in the combined list of atomic
constraints for a normal form) weren't able to determine already an overall
result for the constraint (e.g., false for an AND combination, or true for
an OR combination),
but also that an invalid type/expression always in place for a templated
entity (i.e., regardless of the instantiation) represents an IFNDR case.
That said, I have reported in
https://lists.isocpp.org/std-discussion/2025/01/2783.php the text
associated to both requires expression ([expr.prim.req.general]-p5) and
atomic constraint ([temp.constr.atomic]-p3 and [temp.res.general]-p(6.4)),
and I have noticed two potential problematic topics when an atomic
constraint is made by a requires expression.
I recall them in the following, and refine/fix details of the discussion.
Before discussing the detail of the first 2 questions, it is important to
highlight that the normal form of the constraints associated to a function,
is built according to rules from [temp.constr.normal], where no 'explosion'
is indicated in case of requires expression, which means that a requires
expression boils down to be an atomic constraint even when it contains
multiple requirements (simple, type, compound, nested:
[expr.prim.req.general]-p1).
A) the first topic is for the case when that requires expression contains a
nested requirement, which therefore contains a constraint-expression, in
turn supposed to contain AND / OR operators, combining further nested
constraints/requirements; let's now suppose that one of these nested ones
contains an invalid type/expression, but also that another
constraint/requirement preceding in the lexical order, allows to provide a
true value for the original requires expression.
If I would exactly apply the text of [temp.constr.atomic]-p3, then it reads
that an invalid type/expression (in immediate context) leads soon the
constraint to be not satisfied, whereas the rules from
[expr.prim.req.general]-p5
postpone the check of invalid type/expression for each contained
requirement only after that previous requirements have already been checked
and successfully verified (true result), and similarly the rules from
[temp.constr.op]-p2/p3
state that the constraints conjunctions and disjunctions are checked one by
one, ignoring the residual ones as soon as a constraint allows to get a
logical overall result.
Please, note that in my original post (2783), I erroneuosly considered a
case with false overall logical result for the requires expression, and
invoked only the rules from [expr.prim.req.general]-p5, but this is not a
conflict because the final result as false is provided by both
[temp.constr.atomic]-p3
and [expr.prim.req.general]-p5.
As highlighted in the second post (2787), I really believe that everything
becomes clear and well consistent if the presence of an invaild
type/expression within a requires expression does not mean that the
requires expression is itself an invalid expression. Indeed, this would
represent a hierarchical separation between the atomic constraint and what
is inside the requires expression.
Please, let me know if this is true, and if in your opinion this is in some
way already clear in the standard for any motivation (e.g., concept of
'immediate context', or anything else).
If the solution is in the definition of 'immediate context', don't you
believe that the standard might state clearly something (similar to
[temp.deduct.general]-p9) about the requirement-body not being part of the
immediate context of an atomic constraint corresponding to the requires
expression ? However, in such case, I would be also afraid of formally
incorrectness about the effect of invalid within the requirements of the
requires-expression (i.e., invalid in a non-immediate context for the
original atomic constraint), and therefore some more note should be added
to clarify that any decision is based on the rules for those requirements.
Otherwise (if none of the previous ones apply), do you believe (as I do)
that the standard may be clarified in [temp.constr.atomic]-p3 when an
atomic constraint is made by a requires expression, and eventually
even in [expr.prim.req.general]-p5
in order to introduce a similar 'hierarchical separation' when one of the
requirements is a nested requirement ? (but I don't know if it was really
intended to have also the second mentioned kind of hierarchy... likely not).
B) the second topic is related to the cases of IFNDR when the invalid
type/expression is always in place; indeed, [expr.prim.req.general]-p5
reads that the IFNDR is there anyway, which means regardless of any
satisfation check is performed or not involving the part containing the
invalid type/expression; on the contrary, [temp.res.general]-p(6.4) reads
that the IFNDR is only effective with the additional condition that no
satisfaction check is performed on the constraint-expression containing the
always-invalid type/expression.
But, what happens if the invalid is in an immediate context, a check is
performed, therefore (based on [temp.constr.atomic]-p3) the constraint is
just not satisfied but no ill-forming is notified by the compiler ?
Is it really wanted to drop the IFNDR just because a check was performed ?
Can I state that if the invalid is inside a requires expression, the IFNDR
remains anyway in place based on [expr.prim.req.general]-p5 ?
Was also here any hierarchical separation intended as discussed for
previous topic ?
Note also that [temp.res.general]-p(6.4) makes no distinction between
immediate and non-immediate contexts, nor between templated and
non-templated entities -> is it really wanted not to have IF for
non-immediate contexts ? Not even for non-templated entities (for them, Note
1 in [expr.prim.req.general]-p5 for requires expressions states IF instead
of IFNDR) ?
Note finally that last part of [expr.prim.req.general]-p5 (after Note 1)
seems not to be specific for immediate or non-immediate contexts, but I do
believe that for non-immediate ones the intended behaviour is IF instead of
IFNDR, isn't it ?
Last topic, with a short question:
C) (which was presented since the post 2783):
In [temp.constr.normal], the example in p1.4) reads that the atomic
constraint-expression 'true' has empty mapping.
The point is that no rule from [temp.constr.normal] exactly states the
possibility to get an empty mapping.
We have part p(1.9) as default case always indicating an identity mapping.
I guess it should be extended to indicate empty mapping when the expression
is constant, that is, not involving any template parameter (you know
for sure the best formal words to say it there).
I don't believe it's fair to consider the definition of this special case
just through the example in p(1.4).
Thank you.
Il giorno gio 16 gen 2025 alle ore 01:15 mauro russo <
ing.russomauro_at_[hidden]> ha scritto:
> I thought about the topics once more.
> (https://lists.isocpp.org/std-discussion/current/2783.php)
>
> Maybe the solution about the potential ambiguity between the rules on
> atomic constraints and the rules on requires-clause, is that a
> requires-clause including invalid type/expression, is not itself an invalid
> expression, as this would mean that an atomic constraint being a
> requires-clause means that the requires-clause is well-formed (valid
> expression) and so only the rules for requires-clause apply.
>
> Please, confirm this is true. However, in such a case, I would suggest to
> add a short note in [temp.constr.atomic]. I am not convinced such a note
> would be a 'tutoring'... but you can choose.
>
> Additionally, I still wonder about the text in [temp.res.general] -
> p(6.4), which appear with a different spirit from [expr.prim.req.general] -
> p5, because in case the always-ill-forming is in an immediate context and
> there is any code triggering the check involving that context, the former
> does not lead to IFNDR (nor to a compilation error triggered by the
> existing check), whereas the latter does it (IFNDR for immediate context,
> and of course compilation error for non-immediate context).
>
> Even my third doubt, that is about the need to specify the generation of
> atomic constraints with empty mapping, still applies.
>
> Please, read previous message (mentioned above) of this thread for the
> complete background.
>
Received on 2025-01-29 22:58:06