pharos
pharos copied to clipboard
reasonConstructor rule idea #2
Why would a destructor ever need to write to the destructed object?
I think this can happen (and probably does sometimes) but I agree that this is a good heuristic for choosing destructor or constructor for example.
It's sometimes used to invalidate pointers:
~Foo() {
member_pointer=nullptr;
}
?
It's sometimes used to invalidate pointers:
Yes, I could see that happening in theory. But does production code actually do this? Couldn't a compiler optimize that write away if the destructor doesn't read the nullified value?
I tested this quick, and I wasn't able to get VC to optimize it away.
Clang's behavior was more interesting. If inlining was disabled, it kept the writes in the destructor. But if inlining was enabled, the destructor write was removed. Maybe there is a reason why the write cannot be eliminated from the non-inlined destructor. But I can't think of what that would be. I think only a parent class' destructor would be able to read the value. And Base
obviously does not have a parent class. Maybe there's some virtual base corner case I can't think of.
Anyway, more pragmatically, we should be able to look at programs for which we have ground truth to see how often this happens.
Setting pointers to nullptr
in the destructor is sometimes used in a 'defensive' way when there's a possibility of some part of the code using destructed object's fields. So destruct sets member to null/invalid value and the use of the invalidated field crashes/asserts
Yes, I understand. But after the object has been destructed, reading from the object is undefined behavior, so the compiler is free to optimize it away. And if the reads are optimized away, the writes could be optimized away as well.
Anyway, it's a moot point since MSVC does not do it.