Cost of unnecessary virtual inheritance

Feb 23, 2018 at 2:30pm
Is there any time or space penalty from inheriting virtually when not needed? For example, consider (x->y means "y inherits from x") A -virtual-> B -> C, where there are no other classes in the program. How does this compare to A -> B -> C?
Feb 23, 2018 at 3:36pm
Is there any time or space penalty from inheriting virtually

Most likely, yes for both. If there are virtual functions there will be a need for virtual tables which increases both to some degree.

Like the rest of C++ if you don't need a feature don't use it and you will probably save on one or the other or both.

You may be interested in this SO topic: https://stackoverflow.com/questions/7210412/what-is-the-cost-of-inheritance
Last edited on Feb 23, 2018 at 3:37pm
Feb 23, 2018 at 3:58pm
Most likely, yes for both.
I can make guesses on my own. I don't need to ask anyone to know that it might have a cost. I want to know if it actually has a cost.

If there are virtual functions there will be a need for virtual tables which increases both to some degree.
Virtual functions are orthogonal to virtual inheritance. You can have neither, both, or just one of the two.

Like the rest of C++ if you don't need a feature don't use it and you will probably save on one or the other or both.
I'm asking because in my case I need to generate class definitions from a high-level description, and it turns out that deciding whether a particular inheritance should be virtual or not from an inheritance graph (a DAG) is non-trivial. If the compiler generates code and memory layouts in such a way that inheriting virtually when not needed has basically no cost then I can just always inherit virtually and forget about the problem.

You may be interested in this SO topic: https://stackoverflow.com/questions/7210412/what-is-the-cost-of-inheritance
The question is about virtual inheritance compared to non-virtual inheritance, not inheritance compared to non-inheritance.

Please don't answer if you don't have an answer to the question.
Feb 23, 2018 at 5:20pm
Yes, there is a cost.

Both in size

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>

struct B {int n;};
struct D1 : B {};
struct D2 : virtual B {};

int main()
{
	std::cout << "sizeof(D1) = " << sizeof(D1) << '\n';
	std::cout << "sizeof(D2) = " << sizeof(D2) << '\n';
}
sizeof(D1) = 4
sizeof(D2) = 16
http://cpp.sh/9pudf

and in runtime performance

1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct B {int n;};
struct D1 : B {};
struct D2 : virtual B {};

void f(D1& d1)
{
	d1.n = 10;
}

void f(D2& d2)
{
	d2.n = 10;
}




f(D1&):
    mov DWORD PTR [rdi], 10
    ret


f(D2&):
    mov rax, QWORD PTR [rdi]
    mov rax, QWORD PTR [rax-24]
    mov DWORD PTR [rdi+rax], 10
    ret
https://godbolt.org/g/sgej54
Feb 24, 2018 at 12:32am
Darn. Thanks.
Topic archived. No new replies allowed.