0

Is there a way to understand a behaviour whether it's undefined-unspecified-implementation defined?

If we can't know, how can I avoid using these statements?

Also, if there is a source that I can find these kind of common UB's can you share?

  • https://en.wikipedia.org/wiki/Undefined_behavior#Examples_in_C_and_C++ – Barmar Mar 12 '20 at 08:47
  • That was the first hit when I googled "list of c undefined behaviors" – Barmar Mar 12 '20 at 08:47
  • The real question was that if there was a way to determine these, so I haven't searched any kind of examples. Thanks btw. – Nimbostratus Mar 12 '20 at 08:49
  • "UB" is not a real 'thing'. It's just something that has not officially been addressed in the official specifications, or it *has* been mentioned but with a warning that YMMV per compiler. Look up the specs for your version of C and read them front ti back. – Jongware Mar 12 '20 at 08:49
  • The linked question is for C++, but most of them should apply to C as well. – Barmar Mar 12 '20 at 08:50
  • [Stack Overflow itself](https://stackoverflow.com/search?q=%5Bc%5D+is%3Aa+undefined+behavior) is a great resource, by the way. All kinds of problems caused by stretching the C specs to the breaking point seem to end up being asked about here. – Jongware Mar 12 '20 at 08:52
  • 2
    I think the linked duplicate is missing the point. Question in the title is *How can I know if an attempt is UB and how can I avoid them?*. Key to avoiding UB is to understand of the C language rules, and using defensive practices when designing code. The list of all UB can help, but what C really requires is more disciplined mindset, compared to many other languages. – user694733 Mar 12 '20 at 09:08
  • @Barmar: A C question about undefined behavior is not a duplicate of a C++ question about undefined behavior. – Eric Postpischil Mar 12 '20 at 10:33
  • @EricPostpischil As I said, much of it is common to both languages. Everything about pointers, buffer overflows, integer overflows -- those are the most common sources of UB. – Barmar Mar 12 '20 at 10:47
  • @Barmar: A C question about undefined behavior is not a duplicate of a C++ question about undefined behavior. – Eric Postpischil Mar 12 '20 at 10:48
  • 2
    Annex J.2 of the 2018 C standard lists about 178 circumstances in which behavior is undefined, although some of the list items are themselves multitudinous, such as the first: A “shall” or “shall not” requirement outside of a constraint is violated. The word "shall" appears in 300 sections; I do not know how many of those are constraints. (J.2 is informative; it is a collection of the circumstances from normative portions of the standard.) Given copyright issues, I think J.2 may be too lengthy to copyright verbatim to Stack Overflow. – Eric Postpischil Mar 12 '20 at 10:51
  • 1
    I'd hope your compiler would tell you, when you turn on full warnings and put it in standards mode. GCC in particular has a `-pedantic` flag. – Rup Mar 12 '20 at 10:57
  • 1
    @Rup: Compilers cannot diagnose all instances of undefined behavior, particularly since some of them are run-time issues. – Eric Postpischil Mar 12 '20 at 11:00

1 Answers1

2

The 2018 C standard lists unspecified behaviors in annex J.1, undefined behaviors in J.2, and implementation-defined behavior in J.3. Approximately 350 items are listed, and some of them are multitudinous, such as the first in the undefined category: “A ‘shall’ or ‘shall not’ requirement that appears outside of a constraint is violated (Clause 4).“ The word “shall” appears in 300 sections (I do not know how many are constraints). (Annex J is informative but refers to the normative parts of the standard.)

So even if we listed all the items here, risking violating copyright law, it is not feasible to work day to day by memorizing the cases or even by referring to the list regularly while writing code. Skilled practitioners learn core things that are well defined (which involves unlearning things taught improperly in educational courses) and learn to refer to the standard or other reference material when dealing with things that may not be well defined.

For the most part, a skilled practitioner writes code that is well defined: We have simple objects, simple control flow, pointers are used in “normal” ways, array sizes are respected, and so on. A programmer learns when they need to reflect on something questionable, as when signedness issues may creep into code (as when an unsigned character type is promoted to a signed int) or a need arises to do some “funny business” with pointers. The ability to do this is, for the most part, not explicitly studied; it is acquired with experience.

One does have to become familiar with the most important rules and learn to write code that one knows is defined because one can cite, at least generally, the rules that make it defined. After a student’s initial false bravado has been shaken and they have started to learn the formal rules of the language (in contrast with learning from tutorials that gloss over the rules), they can start to build something of a deduction-based knowledge of the C rules. Then the way you program is to write code that you know works because you know the rules—and when you reach a point where you are not sure, you look up the rules, in the C standard or other documentation. That causes a consider amount of work at first; once has to look up some rules many times before they are fully remembered or even well understood. But it gets easier.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312