Is gcc allowed to eliminate writes in a destructor?
Wed May 20 08:27:00 GMT 2015
I found out about the double delete (or rather infinite delete since
the end condition of a loop was removed by the compiler too), which
would be guarded by setting the pointer to zero. No debugger involved,
also this issue only came up with release builds.
I did not check the resulting assembly, but to me it seems gcc removes
anything thats not externally visibly in the destructor.
Which is kinda ironic because I understood its more or less
recommended at my employers to wipe your data in a destructor, helps
in debugging but its also considered defensive programming so the
object cant be misinterpreted as being "alive and valid".
Thanks for pointing out the relevant section.
2015-05-20 8:46 GMT+02:00 Fabian Cenedese <Cenedese@indel.ch>:
> At 20:55 19.05.2015, Mikhail Maltsev wrote:
>>On 05/19/2015 08:31 PM, Norbert Lange wrote:
>>> I know that using a class after a destructor is called is a nasty
>>> thing and I already changed the code, but I am curious if gcc is
>>> allowed by the standard to eliminate stores to member variables.
>>> I had code similar to the following:
>>> if (_pAlloc) free(_pAlloc);
>>> _pAlloc = 0;
>>> _SomeData = 0;
>>> what happened was that I explicitly called the destructor for
>>> "cleanup" in another method. The free was called, and after the
>>> instance went out of scope it was called again with the same address.
>>Yes, that is allowed, because your program invokes undefined behavior.
>>According to ISO C++11 standard:
>>12.4. <...> "Once a destructor is invoked for an object, the object no
>>longer exists; the behavior is undefined if the destructor is invoked
>>for an object whose lifetime has ended (3.8). [ Example: if the
>>destructor for an automatic object is explicitly invoked, and the block
>>is subsequently left in a manner that would ordinarily invoke implicit
>>destruction of the object, the behavior is undefined. — end example ]"
> I think he's asking not about the double delete but the fact that the
> member was seemingly not zeroed when the second call was made.
> Two possibilities come to mind:
> 1. The debugger showed outdated values.
> 2. The object goes out of scope after the destructor so it doesn't matter
> if _SomeData was set to 0 or not, no one can access it (legally) anyway.
> Therefore it seems that gcc can omit this write unless it's volatile or so.
> Similar to the warning "variable is set but not used" -> no need to do it.
> bye Fabi
More information about the Gcc-help