1

So, I've been reading the C++ standard and came to [defns.undefined] (3.27 in this C++17 draft that I'm reading. Note that while I'm citing C++17 here, I've found similar wording in other standards)--that is the definition of Undefined Behavior. I noticed this wording (emphasis mine):

Note: Undefined behavior may be expected when this International Standard omits any explicit definition of behavior or when a program uses an erroneous construct or erroneous data

Now, thinking about this, this sort of makes sense. It's sort of saying that if the Standard doesn't give a behavior for it, it has undefined behavior. It seems to be saying that if you do something that is out of scope of the Standard, the Standard has nothing to say about it. That makes sense.

However, this is also kind of weird, because I always thought Undefined Behavior had to be explicitly declared by the Standard. Yet, this seems to imply that we should assume Undefined Behavior unless we are told otherwise.

If this is the case, then couldn't there be instances of Undefined Behavior that are Undefined Behavior because the Standard didn't explicitly give a behavior for some construct? And if such a thing is possible, could is it possible to generate an example (that would still compile) of Undefined Behavior that is Undefined Behavior because of this wording, or would anything that fall under this be near impossible to construct for some reason?

  • 2
    _this seems to imply that we should assume Undefined Behavior unless we are told otherwise_ This was obvious, wasn't it? – Language Lawyer Nov 15 '19 at 20:58
  • Not until I read that :D. –  Nov 15 '19 at 20:59
  • 2
    Do note that notes are non-normative. That little blurb actually has sections of the standard supporting it, you'd just need to hunt them down. – NathanOliver Nov 15 '19 at 20:59
  • 2
    Seems closely related to this Q&A https://stackoverflow.com/questions/26526426/is-something-undefined-behavior-by-omission – StoryTeller - Unslander Monica Nov 15 '19 at 21:01
  • Read the bullet points here: https://en.cppreference.com/w/cpp/language/ub – Richard Critten Nov 15 '19 at 21:02
  • @StoryTeller-UnslanderMonica Very close indeed. The only thing is I am asking if it is possible to generate code that has this happen, which the other question doesn't go into. But very close. I might consider marking it a dupe. I'll have to give it some thought first though. –  Nov 15 '19 at 21:04
  • @RichardCritten I'm not sure I understand your point. –  Nov 15 '19 at 21:05
  • The question is about C++, but the C standard is explicit: *If a "shall" or "shall not" requirement that appears outside of a constraint or runtime-constraint is violated, the behavior is undefined. Undefined behavior is otherwise indicated in this International Standard by the words "undefined behavior" or by the omission of any explicit definition of behavior. There is no difference in emphasis among these three; they all describe "behavior that is undefined".* – Keith Thompson Nov 15 '19 at 21:14

2 Answers2

4

If this is the case, then couldn't there be instances of Undefined Behavior that are Undefined Behavior because the Standard didn't explicitly give a behavior for some construct?

I think this is the correct point of view. If the standard "accidentally" omits a specification of how a particular construct behaves, but it's something that we all know "should" be well-defined, then it's a defect in the standard and needs to be fixed. If, on the other hand, it's a construct that "should" be UB, then the standard is already "correct" (although there are benefits to being explicit).

For example, the standard fails to mention what happens if typeid is applied to an lvalue of polymorphic class type if the object's constructor has not yet begun executing or the destructor has completed. Therefore, the behaviour is undefined by omission. It's also something that's "obviously" UB. So there is no problem.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312
  • Excellent. Thank you for generating an example. –  Nov 15 '19 at 21:08
  • I think vector's contiguity was one of those "accidental UB's" ; it was fixed in C++03. – MSalters Nov 16 '19 at 02:37
  • Given that the authors of the C Standard explicitly recognize that a poor quality implementation could be conforming without being able to meaningfully process any programs that aren't contrived and useless, I don't think they were worried about whether things that were obvious were actually defined, or considered the fact that some such things weren't actually defined as a "defect". – supercat Nov 16 '19 at 20:51
2

is it possible to generate an example (that would still compile) of Undefined Behavior that is Undefined Behavior because of this wording

The classic example is indirection through a null pointer (CWG232):

*(int*)nullptr;

[expr.unary.op]/1 says that the result of applying the indirection operator is an lvalue which denotes the object to which the argument of the operator points to, whilst null pointer doesn't point to any object. So indirection through a null pointer is UB by omission of explicit definition of behavior for the case when the argument doesn't point to an object.

Language Lawyer
  • 3,378
  • 1
  • 12
  • 29