I know that a destructor in C++ does not return a value and its type cannot be explicitly specified.
However, I am wondering whether it can be considered an implicitly void
function and whether such a classification is correct according to the C++ standard.
I created a program where type of X destructor is void
.
#include <iostream>
#include <cxxabi.h>
using namespace std;
class X
{
};
int main()
{
X *x = new X();
char *fullname;
using destructor_type = decltype(x->~X());
const type_info &destructor_t = typeid(destructor_type);
fullname = abi::__cxa_demangle(destructor_t.name(), NULL, NULL, NULL);
cout << "[DESTRUCTOR] => " << destructor_t.name() << " => " << fullname << '\n';
free(fullname);
}
Can you explain to me how it is with destructor?
I know that a destructor in C++ does not return a value and its type cannot be explicitly specified.
However, I am wondering whether it can be considered an implicitly void
function and whether such a classification is correct according to the C++ standard.
I created a program where type of X destructor is void
.
#include <iostream>
#include <cxxabi.h>
using namespace std;
class X
{
};
int main()
{
X *x = new X();
char *fullname;
using destructor_type = decltype(x->~X());
const type_info &destructor_t = typeid(destructor_type);
fullname = abi::__cxa_demangle(destructor_t.name(), NULL, NULL, NULL);
cout << "[DESTRUCTOR] => " << destructor_t.name() << " => " << fullname << '\n';
free(fullname);
}
Can you explain to me how it is with destructor?
Share Improve this question asked Feb 6 at 20:10 patb0patb0 431 silver badge2 bronze badges New contributor patb0 is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct. 5 |1 Answer
Reset to default 5Note that the difference between an ordinary function's type and its return type. Given the declaration
double f(int);
the type of f
is double(int)
or "function of int
returning double
". The return type of f
is double
.
To be technically correct (the best kind of correct):
- A destructor does not have a type.
- A destructor does not have a return type.
- A function call expression whose function part names a destructor (like
x->~X()
) has typevoid
.
So,
struct X { ~X(); };
X x;
// Both are errors: Naming a destructor can only be done in
// a declaration or definition, or in a call expression with ().
// If they were valid, the destructor has no type anyway.
using T1 = decltype(X::~X);
using T2 = decltype(x.~X);
using T3 = decltype(x.~X());
static_assert(std::is_same_v<T3, void>); // OK
Note that sometimes decltype
gives the type from a name's declaration and sometimes it gives a type based on the type and value category of the expression. This is why decltype(a)
and decltype((a))
can be different things. But x.~X()
is not directly naming the destructor, so it falls into the category of just getting the expression type, not involving the declaration (explicit or implicit) of ~X
.
It's true a destructor is in many ways like a function with return type void
: You can use the statement return;
, you can't use return
with any actual value, and you can't get a value from an expression that calls it.
But there's one little difference showing that a destructor doesn't actually have return type void
: A function with return type void
can return
an expression that has type void
. A destructor can't return
any expression, even if it does have type void
.
void f();
void g(bool b) {
if (b)
return f(); // OK, returning void expression as void
else
return void(); // Strange but valid way of writing "return;"
}
Y::~Y() {
if (this->b)
return f(); // Error, can't put anything after "return"
else
return void(); // Error
}
void
is not a function type, it's a data type. For example the type ofvoid foo(int a)
is not "void", it'svoid(int)
aka "function taking an int parameter and returning void". E.g.void bar()
's type is not "void" either, it's type isvoid()
aka "function taking no parameter and returning void". – bolov Commented Feb 6 at 21:45int foo = 24
isint
then they make the pattern that the type of a symbol (id) is just the type that appears before that id. This leads them to say/think that the type ofint foo(int a, bool b)
is "int" , but that's incorrect. As per my previous comment it's "function taking an int and a bool parameters and returning int". – bolov Commented Feb 6 at 21:49void
– Igor Tandetnik Commented Feb 7 at 1:37