Observable behavior and undefined behavior — What happens if I don't call a destructor?

后端 未结 13 2653
滥情空心
滥情空心 2020-12-03 06:48

Note: I\'ve seen similar questions, but none of the answers are precise enough, so I\'m asking this myself.

This is a very nitpicky "language-lawye

13条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-03 07:45

    First of all, we need to define undefined behavior, which according to the C FAQ would be when:

    Anything at all can happen; the Standard imposes no requirements. The program may fail to compile, or it may execute incorrectly (either crashing or silently generating incorrect results), or it may fortuitously do exactly what the programmer intended.

    Which, in other words, means that the programmer cannot predict what would happen once the program is executed. This doesn't mean that the program or OS would crash, it simple means that the program future state would only be know once that it is executed.

    So, explained in math notation, if a program is reduced to a function F which makes a transformation from an initial state Is into a final state Fs, given certain initial conditions Ic


    F(Is,Ic) -> Fs


    And if you evaluate the function (execute the program) n times, given that n-> ∞


    F(Is,Ic) -> Fs1, F(Is,Ic) -> Fs2, ..., F(Is,Ic) -> Fsn, n-> ∞


    Then:

    • A defined behavior would be given by all the resulting states being the same: Fs1 = Fs2 = ... = Fsn, given that n-> ∞
    • An undefined behavior would be given by the possibility of obtaining different finished states among different executions. Fs1 ≠ Fs2 ≠ ... ≠ Fsn, given that n-> ∞

    Notice how I highlight possibility, because undefined behavior is exactly that. There exists a possibility that the program executes as desired, but nothing guarantees that it would do so, or that it wouldn't do it.

    Hence, answering your answer:

    Is forgetting to call a destructor any different than forgetting to call an ordinary function with the same body?

    Given that a destructor is a function that could be called even when you don't explicitly call it, forgetting to call a destructor IS different from forgetting to call an ordinary function, and doing so COULD lead to undefined behavior.

    The justification is given by the fact that, when you forget to call an ordinary function you are SURE, ahead of time, that that function won't be called at any point in your program, even when you run your program an infinite number of times.

    However, when you forget to call a destructor, and you call your program an infinite number of times, and as is exemplified by this post: https://stackoverflow.com/questions/3179494/under-what-circumstances-are-c-destructors-not-going-to-be-called under certain circumstances, C++ destructors are not called, it means that you can't assure beforehand when the destructor would be called, nor when it wouldn't be. This uncertainty means that you can't assure the same final state, thus leading to UB.

    So answering your second question:

    Under which condition(s), if any, does this program exhibit Undefined Behavior?

    The circumstances would be given by the circumstances when the C++ destructors are not called, given on the link that I referenced.

提交回复
热议问题