Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any practical reason to check if something is destructible before calling its destructor?

Tags:

c++

So I've been messing around trying to implement a variant/tagged union class and needed a way to write generic destructors and made what I thought was a silly mistake forgetting that some types don't have destructors, doing something like

template<typename T> 
void destruct(T& thing) {
    thing.~T();
}

Yet, this worked fine even with types that didn't have destructors, like int or struct A {int b;};. I still think it's more readable and easier to reason with something that uses something like this

template<typename T>
void destruct(T& thing) {
    if constexpr(std::is_destructible<T>::value) {
        thing.~T();
    }
}

But is there actually any difference between the code? The first one feels pretty undefined behavoiry/just wrong to me.

like image 732
Jake Schmidt Avatar asked Mar 02 '23 09:03

Jake Schmidt


1 Answers

Yet, this worked fine even with types that didn't have destructors, like int or struct A {int b;};

Those are examples of types that are trivially destructible. It is well defined to invoke their "destructor". It has no effects.

But is there actually any difference between the code?

Only for types that are not destructible. Trivially destructible types are destructible.

For non-destructible types such as void, function types, or types with ~T() = delete;, the first function is ill-formed while the latter is well-formed with empty body. It depends on the use case which one is more useful, but silently ignoring attempt to destroy something that is not destructible seems dubious to me.

like image 90
eerorika Avatar answered May 10 '23 21:05

eerorika