If t
is permitted to fall out of scope, it will be destroyed. That is problematic if the type has a destructor with side-effects; for example, assume that we have a destructor on a file that closes the file handle contained in itself. This would mean that on a swap
call, one of the file handles would be closed, which is certainly undesirable. Any ~T
has a destructor also: it frees the memory. If you were to immediately run the destructor, the memory would be freed, and so you would have a use-after-free/double-free bug.
forget(t)
does not of itself result in a memory leak because inside forget
, it takes its parameter by value, on the stack. Thus, when it returns, the stack memory is freed. If you were to forget a ~T
, that ~T
would indeed leak memory; but that is not what's happening in this case at all, even if you are swapping with T
as ~U
, because of the semantics: t
is simply scratch space; just before the cast::forget(t)
call, there is actually unsoundness, because the same memory is addressed by two owned pointers; that's why one is simply forgotten without running the destructor.
The point of the matter is that forget
should only be used where you are moving a value about and so something that will run its destructor does actually still exist. You shouldn't use it in any other situation, or you can leak memory.