← Back to context

Comment by maple3142

9 hours ago

Is this a correct understanding of UB in C? A program P has a set of inputs A that do not trigger UB, and a complementary set of inputs B that do trigger UB. A correct compiler compiles P into an executable P'. For all inputs in A, P' should behave the same as P. However, for any input in B, the is absolutely no requirements on the behavior of P'.

Intuitively yes - the program will be compiled as if B-inputs are never passed to the program, and that can include eliminating code that tries to detect B-inputs.

  • This is a description of an imaginary compiler, evoked by the ANSI/ISO standards documents, which has never existed and will never exist. To understand what the program will do, you just have to understand the compiler behavior on your target platforms. A helpful intuition pump is: imagine the ANSI/ISO specifications simply do not exist; now what? Well, you just continue your engineering practice, the way you would for any of the myriad languages that never even had a post hoc standards document.

    • > just

      That word is carrying a lot of weight here. Compilers are unbelievably complex these days, and it's impossible for any one human to fully understand the entire compilation process, including the effects of any arbitrary combination of compiler flags.

      Any assumptions you have about what the compiler does in the face of UB will collapse on the next patch release of that compiler, or the moment somebody changes the compiler flags, or the moment somebody tries to compile the code for a slightly different OS, not to mention architecture.

      There is no other way to understand what C compilers do than reading the standard.

      3 replies →

    • GCC -O1 and clang -O1 will both optimize this function under the assumption that inputs that cause signed integer overflow are never passed:

          int will_overflow(int a, int b) {
              int sum = a + b;
              if (b > 0 && sum < a)
                  return 1;
              return 0;
          }

      5 replies →

    • Not imaginary. Eliding checks on nullptr and integer overflow were both implemented, shipped, miscompiled the linux kernel and grew flags to disable them. I expect there are more if one goes looking.

      1 reply →