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

后端 未结 13 2699
滥情空心
滥情空心 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:42

    In the comments you've left a simple question that made me rethink what I said. I've removed the old answer because even if it had some value, it was far from the point.

    So you're saying my code is well-defined, since it "doesn't depend on that even if I print it"? No undefined behavior here?

    Let me say again that I don't precisely remember the definition of placement new operator and deallocation rules. Actually, I've not even read the newest C++ standard in full. But if the text you quoted is from there, then you are hitting the UB.

    Not due to Rand or Print. Or anything we "see".

    Any UB that occurs here is because your code assumes that you can safely "overwrite" an old 'object' without destroying the previous instance that was sitting at that place. The core sideeffect of a destructor is not "freeing handles/resources" (which you do manually in your code!) but leaving the space "ready for being reclaimed/reused".

    You have assumed that the usage of the memory chunks and lifetimes of objects are not well-tracked. I'm pretty sure that the C++ standard does not define that they are untracked.

    For example, imagine that you have the same code as provided, but that this struct/class has a vtable. Imagine that you are using hyper-picky compiler which has tons of debugchecks that manages the vtable with extra care and allocates some extra bitflag and that injects code into base constructors and destructors that flips that flag to help to trace errors. On such compiler, this code would crash on the line of new (r) MakeRandom since first object's lifetime has not been terminated. And I'm pretty sure that such picky compiler would still be fully C++ compliant, just as your compiler surely is too.

    It's an UB. It's only that most compilers really don't do such checks.

提交回复
热议问题