inline virtual destructor in a header file??

Q

qazmlp

My class in a header file, contains inline virtual destructor.
Is this Ok? Can it cause any problems?

class base
{
public:
base() { }
virtual ~base { std::cout<<"Inside virtual destructor\n"; }

// Other members
};
 
J

John Harrison

qazmlp said:
My class in a header file, contains inline virtual destructor.
Is this Ok? Can it cause any problems?

class base
{
public:
base() { }
virtual ~base { std::cout<<"Inside virtual destructor\n"; }

// Other members
};

It's fine, in fact its common. Why shouldn't it be OK?

john
 
P

Patrik Stellmann

qazmlp said:
My class in a header file, contains inline virtual destructor.
Is this Ok? Can it cause any problems?

class base
{
public:
base() { }
virtual ~base { std::cout<<"Inside virtual destructor\n"; }

// Other members
};
If you declare a function as inline it doesn't mean that the compiler
*has* to inline that code - which usually wouldn't work with virtual
functions - you just 'suggest' that he *could* inline it. So it's all
right with that...
 
A

Andrey Tarasevich

qazmlp said:
My class in a header file, contains inline virtual destructor.
Is this Ok? Can it cause any problems?

It can't. What excactly makes you to worry about it?
 
J

jeffc

John Harrison said:
It's fine, in fact its common. Why shouldn't it be OK?

Because it's "inline" and it's also "virtual". You don't see why that might
be contradictory and confusing?
 
A

Andrey Tarasevich

jeffc said:
Because it's "inline" and it's also "virtual". You don't see why that might
be contradictory and confusing?
...

It shouldn't be contradictory and/or confusing to a person who fully
understands the meaning of these qualifiers in C++.
 
C

Claudio Puviani

jeffc said:
Because it's "inline" and it's also "virtual". You don't see why that might
be contradictory and confusing?

Virtual functions can be inlined. The compiler can determine by context whether
to inline the code or do a polymorphic call. For example, if you invoke a
virtual method directly on an object (not a reference or a pointer), the
compiler MAY choose to inline the code, since there's no ambiguity. Or it can
make a direct (non-vtable) call to the out-of-line function. If you're calling
the same virtual function through a pointer or a reference, the compiler must
then select the appropriate function through the vtable. This implies that you
may (and probably will) have both an out-of-line and inline implementations of
your function if (a) it's inlineable, and (b) you call it directly at some
point.

A detail to remember: when you invoke a method from within the object, it's
invoked through the 'this' pointer, which means that unless you qualify it, you
always get a polymorphic call.

Claudio Puviani
 
J

John Harrison

Andrey Tarasevich said:
It shouldn't be contradictory and/or confusing to a person who fully
understands the meaning of these qualifiers in C++.

It seems to be a very common misunderstanding that the meaning of the
keyword inline has something to do with inlining function calls (easy to see
how that misunderstanding would occur). However the only meaning that the
C++ standard gives to inline functions is as an exception to the one
definition rule, thereby allowing inline functions to usefully appear in
header files.

In any case there are cases where a virtual function is called via a
non-virtual mechanism, this is especially true of a destructor.

john
 
J

jeffc

Andrey Tarasevich said:
It shouldn't be contradictory and/or confusing to a person who fully
understands the meaning of these qualifiers in C++.

Use your head man - does the originator of this thread sound like someone
who "fully understands the meaning of these qualifiers in C++"?
 
J

Jonathan Turkanis

John Harrison said:
It seems to be a very common misunderstanding that the meaning of the
keyword inline has something to do with inlining function calls (easy to see
how that misunderstanding would occur). However the only meaning that the
C++ standard gives to inline functions is as an exception to the one
definition rule, thereby allowing inline functions to usefully appear in
header files.

It does have 'something to do' with inlining function calls:

"The inline specifier indicates to the implementation that inline
substitution of the function body at the point of call is to be
preferred to the usual function call mechanism." (7.1.2)

Inlining is not required, as you know, but it's a bit of an
overstatement to say that 'inline' is completely unrelated to
inlining.

Jonathan
 
L

lilburne

Claudio said:
Virtual functions can be inlined. The compiler can determine by context whether
to inline the code or do a polymorphic call. For example, if you invoke a
virtual method directly on an object (not a reference or a pointer), the
compiler MAY choose to inline the code, since there's no ambiguity.

Inline destructors, whether virtual or not, can be a cause
of code bloat:

#include <string>
#include <vector>

using namespace std;

class A {
string name;
string address;
string telephone;
public:
A() {};
virtual void function() {}
virtual ~A() {}
};

class B : public A {
public:
B() {};
void function() {}
~B() {}
};

void abc() {
B b;
b.function();
}

int main()
{
B b;
b.function();
abc();
return 0;
}

check the assembler output from the above, and compare it to
the output where the destructors are defined outline.
 
N

Nick Hounsome

qazmlp said:
My class in a header file, contains inline virtual destructor.
Is this Ok? Can it cause any problems?

class base
{
public:
base() { }
virtual ~base { std::cout<<"Inside virtual destructor\n"; }

// Other members
};

1. don't try to inline stuff that is not trivial - template I/O is never
trivial - it's a horrendous mess of
inlined template stuff with conditions loops, exceptions etc. that the
compiler is virtually certain
do decide is way too hard to inline.
2. Apart from that inlining virtual dtors is a good idea if they are
trivial -
Every derived class dtor whether explicit or implicit will call the base
class dtor - if this can be inlined then
this should result in saving a function call.
3. The only other problem for trivial dtors is if the base class is ever
instantiated - If it is it will need a vtable
which will need an outline dtor. If you add a pure virtual method (the
dtor can be pure even if defined)
then the compiler should realise that the class cannot be instantiated
and
hence it will never need a vtable and hence never need an outlined dtor.
4. your compiler might not be that smart.
 
C

Claudio Puviani

lilburne said:
Inline destructors, whether virtual or not, can be a cause
of code bloat:

Any inline function -- destructor or otherwise -- can be a source of code bloat
if the inlining wasn't chosen judiciously. In the example you gave, the bloat
comes from inlining a destructor that implicitly called three other destructors.
The problem wasn't that _a_ destructor was inlined, but that that particular
destructor shouldn't have been inlined if code size had been your criterion for
inlining.

To counterbalance your example, an inlined trivial destructor could be
completely optimized out, whereas the same trivial destructor out-of-line would
still cause invocation code to be generated everywhere an object of that type is
destroyed.

Code bloat, bad performance, sub-optimal memory usage... those are all results
of bad programming, not of using a specific language feature.

Claudio Puviani
 
J

John Harrison

Jonathan Turkanis said:
It does have 'something to do' with inlining function calls:

"The inline specifier indicates to the implementation that inline
substitution of the function body at the point of call is to be
preferred to the usual function call mechanism." (7.1.2)

Inlining is not required, as you know, but it's a bit of an
overstatement to say that 'inline' is completely unrelated to
inlining.

Jonathan

I chose my words carefully (perhaps not carefully enough). The point I was
trying to make was that the meaning of a program is unaffected by whether a
function call is inlined or not, also a programs legality is unaffected by
whether a function call is inlined or not. That's why I said the *meaning*
of the keyword inline. I wasn't trying to say that inline is completely
unrelated to function call inlining.

john
 
J

Jonathan Turkanis

John Harrison said:
I chose my words carefully (perhaps not carefully enough). The point I was
trying to make was that the meaning of a program is unaffected by whether a
function call is inlined or not, also a programs legality is unaffected by
whether a function call is inlined or not. That's why I said the *meaning*
of the keyword inline. I wasn't trying to say that inline is completely
unrelated to function call inlining.

Okay -- I'll resist the tempatation to argue about the meaning of
'meaning'. ;-)

Jonathan
 
J

John Harrison

Jonathan Turkanis said:
Okay -- I'll resist the tempatation to argue about the meaning of
'meaning'. ;-)

Jonathan

The word 'meaning' has only one meaning, I refer you to 1.9.1 of the C++
standard, especially footnote 5.

john
 
J

Jonathan Turkanis

The word 'meaning' has only one meaning, I refer you to 1.9.1 of the C++
standard, especially footnote 5.

Search the standard for 'meaning'. You'll find that even in
standardese, 'meaning' has many meanings.

But I said I wouldn't argue.

Jonathan
 
L

lilburne

Claudio said:
Code bloat, bad performance, sub-optimal memory usage... those are all results
of bad programming, not of using a specific language feature.

I didn't say that it was anything to do with a particular
language feature. The point was that what might look like a
trivial piece a code (a destructor that looks like it has no
body) sometimes isn't.

If the class contains nothing but PODs there is no overhead.
Once you have a class that contains a member that requires a
non-trivial dtor you'll have the problem illustrated, which
may be added in 6 months time. How many newbies do you think
would be aware of the overhead of such destructors?
 
Q

qazmlp

Andrey Tarasevich said:
It can't. What excactly makes you to worry about it?

As I remember, inline and virtual cannot co-exist.
So, I wanted to know whether there will be a problem, if the compiler
makes the virtual destructor as inline.

As the reply posts have confirmed that there is no problem, it is
fine.

Thanks!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top