You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
CWG2823 [expr.unary.op] p1 should explicitly specify the behavior if the expression does not refer to the object or function #198
I guess this is covered (perhaps non-normative?) "implicit undefined behavior" rule ([defns.undefined]/Note 1). So this case is undefined even though not explicitly stated. There's a similar normative rule in C.
Such UB may be subject to change, see CWG232 and CWG315.
Perhaps we need a paper to eliminate all implicit UB, because sometimes it's difficult to determine whether some given behavior is undefined or unspecified.
I would really welcome the suggested change here. This bit in the standard is a topic of recurring questions, and it always takes unfortunately long to explain that a null pointer does not point to an object, and hence dereferencing it is undefined behavior. We have a similar problem at [expr.ref]/6.2, where we say "the expression designates the corresponding member subobject of the object designated by the first expression". There we don't (bother) say(ing) that if no object is designated, we are in the land of UB. That tends to take even longer to explain than the unary operator*. Even if we end up making mere operator* of a null pointer well-defined (See https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#232), in all likelihood we'll still (continue to) require that the LHS of an operator-> must be non-null, and questions about that will continue. Unless we just clarify it, along the lines of what's been suggested here.
changed the title [-][expr.unary.op] p1 should explicitly specify the behavior if the expression does not refer to the object or function[/-][+]CWG232 [expr.unary.op] p1 should explicitly specify the behavior if the expression does not refer to the object or function[/+]on Dec 15, 2022
Perhaps we need a paper to eliminate all implicit UB, because sometimes it's difficult to determine whether some given behavior is undefined or unspecified.
Yes, this is what I think about here. Read the rule with an implication meaning that would vary to different readers is frowned upon. Explicitly specify what the behavior should be is clear and unambiguous.
No requirement == undefined behavior by definition.
Before I posted this issue, I knew the rule may be interpreted by the implication meaning(i.e. if we didn't specify the behavior, the behavior can be subsumed to undefined behaviors, which is its literal meaning). However, assume [expr.unary.op] p1 falls into UB if the expression is a null pointer value, then how about [expr.typeid] p3
If the glvalue is obtained by applying the unary * operator to a pointer and the pointer is a null pointer value ([basic.compound]), the typeid expression throws an exception ([except.throw]) of a type that would match a handler of type std::bad_typeid exception ([bad.typeid]).
Since *(NULL) has been assumed to be UB, why typeid(*(NULL)) instead has the defined behavior? This is contradictory here. So, explicitly defining what behavior should be is looked forward to, instead of by guess, I think.
The normative wording is the definition, but not the rule of reasoning if the term is not existing in the use sites at the first place, i.e. you cannot get the logical consequeces in both direction randomly. Just like most formal languages (and programming languages), plain English is also not a system having such property in nature.
If you want to make such a way of reasoning working, you must have some additional meta rules. Such rules can be added by ISO documents normatively, but I don't find such, and I think it is out of the scope of ISO C++. Further, allowing such meta rules potentionally makes the specification (or more seriously, all standards) suffer from higher risks of ambiguity globally, so I don't think it legitemate.
In general, I think we want to be explicit about undefined behavior in C++. "Undefined behavior by omission" is frowned upon.
This is quite important. I guess this is also the reason that ISO C++ lacks the fallback normative rule equivalent to ISO C 4/2, delibrately. However, the current wording is not intuitive for readers to get the point. We should probably make the intent more normative.
undefined behavior
behavior, such as might arise upon use of an erroneous program construct or erroneous data, for which this International Standard imposes no requirements. Undefined behavior may also be expected when this International Standard omits the description of any explicit definition of behavior. [ Note: [...] — end note ]
And then the sentence "Undefined behavior may also be expected when [...]." was moved into the note in N3126, even without any editorial mark. The reason of this change wasn't found in the editor's report N3127.
changed the title [-]CWG232 [expr.unary.op] p1 should explicitly specify the behavior if the expression does not refer to the object or function[/-][+]CWG2823 [expr.unary.op] p1 should explicitly specify the behavior if the expression does not refer to the object or function[/+]on Nov 15, 2023
Activity
frederick-vs-ja commentedon Dec 15, 2022
I guess this is covered (perhaps non-normative?) "implicit undefined behavior" rule ([defns.undefined]/Note 1). So this case is undefined even though not explicitly stated. There's a similar normative rule in C.
Such UB may be subject to change, see CWG232 and CWG315.
Perhaps we need a paper to eliminate all implicit UB, because sometimes it's difficult to determine whether some given behavior is undefined or unspecified.
languagelawyer commentedon Dec 15, 2022
The rule is normative: behavior for which this document imposes no requirements. No requirement == undefined behavior by definition.
jensmaurer commentedon Dec 15, 2022
In general, I think we want to be explicit about undefined behavior in C++.
"Undefined behavior by omission" is frowned upon.
villevoutilainen commentedon Dec 15, 2022
I would really welcome the suggested change here. This bit in the standard is a topic of recurring questions, and it always takes unfortunately long to explain that a null pointer does not point to an object, and hence dereferencing it is undefined behavior. We have a similar problem at [expr.ref]/6.2, where we say "the expression designates the corresponding member subobject of the object designated by the first expression". There we don't (bother) say(ing) that if no object is designated, we are in the land of UB. That tends to take even longer to explain than the unary operator*. Even if we end up making mere operator* of a null pointer well-defined (See https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#232), in all likelihood we'll still (continue to) require that the LHS of an operator-> must be non-null, and questions about that will continue. Unless we just clarify it, along the lines of what's been suggested here.
languagelawyer commentedon Dec 15, 2022
@villevoutilainen thanks for reminding that this issue is just CWG232
[-][expr.unary.op] p1 should explicitly specify the behavior if the expression does not refer to the object or function[/-][+]CWG232 [expr.unary.op] p1 should explicitly specify the behavior if the expression does not refer to the object or function[/+]xmh0511 commentedon Dec 16, 2022
Yes, this is what I think about here. Read the rule with an implication meaning that would vary to different readers is frowned upon. Explicitly specify what the behavior should be is clear and unambiguous.
xmh0511 commentedon Dec 16, 2022
Before I posted this issue, I knew the rule may be interpreted by the implication meaning(i.e. if we didn't specify the behavior, the behavior can be subsumed to undefined behaviors, which is its literal meaning). However, assume [expr.unary.op] p1 falls into UB if the expression is a null pointer value, then how about [expr.typeid] p3
Since
*(NULL)has been assumed to be UB, whytypeid(*(NULL))instead has the defined behavior? This is contradictory here. So, explicitly defining what behavior should be is looked forward to, instead of by guess, I think.languagelawyer commentedon Dec 16, 2022
If assuming the rule «Behavior of evaluating of an expression E does not depend on its context», then yes. But there is no such rule.
FrankHB commentedon Feb 10, 2023
The normative wording is the definition, but not the rule of reasoning if the term is not existing in the use sites at the first place, i.e. you cannot get the logical consequeces in both direction randomly. Just like most formal languages (and programming languages), plain English is also not a system having such property in nature.
If you want to make such a way of reasoning working, you must have some additional meta rules. Such rules can be added by ISO documents normatively, but I don't find such, and I think it is out of the scope of ISO C++. Further, allowing such meta rules potentionally makes the specification (or more seriously, all standards) suffer from higher risks of ambiguity globally, so I don't think it legitemate.
FrankHB commentedon Feb 10, 2023
This is quite important. I guess this is also the reason that ISO C++ lacks the fallback normative rule equivalent to ISO C 4/2, delibrately. However, the current wording is not intuitive for readers to get the point. We should probably make the intent more normative.
frederick-vs-ja commentedon Apr 6, 2023
I guess this is intended, but the motivation seems mysterious and not well recognized.
N3090 [defns.undefined] used to say
And then the sentence "Undefined behavior may also be expected when [...]." was moved into the note in N3126, even without any editorial mark. The reason of this change wasn't found in the editor's report N3127.
frederick-vs-ja commentedon Nov 15, 2023
This should have been superseded by CWG2823.
[-]CWG232 [expr.unary.op] p1 should explicitly specify the behavior if the expression does not refer to the object or function[/-][+]CWG2823 [expr.unary.op] p1 should explicitly specify the behavior if the expression does not refer to the object or function[/+]