virtual & casting

A

Alex Vinokur

classes that have virtual methods hold pointer to virtual table as
additional implicit data member. So, sizeof of such classes is sizeof
of all data (as struct-POD) plus 4.
It seems that use of casting for such classes is quite dangerous.
See sample below.

Why does reinterpret_cast permit such a casting?

=====================
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for
80x86

====== foo.cpp ======
#include <iostream>
using namespace std;

#define BUF_SIZE 8
#define SHOW(x) cout << #x << " = " << x << endl

struct Foo1
{
void foo() {} // non-virtual
char m_buf[BUF_SIZE];
void display(int in_start = 0)
{
cout << "Foo1 [" << in_start << ", " << (sizeof (m_buf) - 1) << "]
= ";
for (int i = in_start; i < static_cast<int>(sizeof (m_buf)); i++)
{
cout << m_buf;
}
cout << endl;
}

};

struct Foo2
{
virtual void foo() {} // virtual
char m_buf[BUF_SIZE];
void display(int in_start = 0)
{
cout << "Foo2 [" << in_start << ", " << (sizeof (m_buf) - 1) << "]
= ";
for (int i = in_start; i < static_cast<int>(sizeof (m_buf)); i++)
{
cout << m_buf;
}
cout << endl;
}

};

void display (char* in_p, int in_len, char* in_name)
{
cout << in_name << " (buf-size = " << in_len << ") : ";
for (int i = 0; i < in_len; i++)
{
cout << in_p;
}
cout << endl;
}

int main()
{
SHOW (sizeof (Foo1));
SHOW (sizeof (Foo2));


char buf1[BUF_SIZE];
char buf2[BUF_SIZE];
memcpy(buf1, "abcdxyz1", sizeof (buf1));
memcpy(buf2, "abcdxyz2", sizeof (buf2));

Foo1* p1 = reinterpret_cast<Foo1*>(buf1);
Foo2* p2 = reinterpret_cast<Foo2*>(buf2);
cout << endl;
p1->display();
p2->display();
p2->display(-4);


Foo1 foo1;
Foo2 foo2;
memcpy(foo1.m_buf, "qwertyu1", sizeof (foo1.m_buf));
memcpy(foo2.m_buf, "qwertyu2", sizeof (foo2.m_buf));
cout << endl;
foo1.display();
foo2.display();

char* pch1 = reinterpret_cast<char*>(&foo1);
char* pch2 = reinterpret_cast<char*>(&foo2);

cout << endl;
display (pch1, BUF_SIZE, "pch1");
display (pch2, BUF_SIZE, "pch2");
display (pch2, BUF_SIZE + 4, "pch2");

return 0;

}
=====================


====== Run ======

sizeof (Foo1) = 8
sizeof (Foo2) = 12

Foo1 [0, 7] = abcdxyz1
Foo2 [0, 7] = xyz2€A
Foo2 [-4, 7] = abcdxyz2€A

Foo1 [0, 7] = qwertyu1
Foo2 [0, 7] = qwertyu2

pch1 (buf-size = 8) : qwertyu1
pch2 (buf-size = 8) : ₪!A qwer
pch2 (buf-size = 12) : ₪!A qwertyu2

=================

Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn
 
O

ondra.holub

You may not be sure that sizeof of all data + 4 bytes is sizeof of
whole instance, because there may be aligning and pointer is not always
4 bytes big.

reinterpret_cast allows it, because reinterpret_cast does almost
nothing. It only changes one pointer type to other pointer type without
any conversions. So you have to be sure you know what are you doing,
becasue you (as programmer) are taking the responsibility of the type
corectness here.
 
V

VJ

Alex said:
classes that have virtual methods hold pointer to virtual table as
additional implicit data member. So, sizeof of such classes is sizeof
of all data (as struct-POD) plus 4.
It seems that use of casting for such classes is quite dangerous.
See sample below.

Why does reinterpret_cast permit such a casting?


Besides:
h.cpp:24: warning: 'struct Foo2' has virtual functions but non-virtual
destructor

I dont see whats the problem.

Foo1* p1 = reinterpret_cast<Foo1*>(buf1);

Try this:
int pch1 = reinterpret_cast<int>(&foo1);
std::cout<<pch1<<std::endl;


reinterpret_cast transforms 1 type to another, and these two dont have
to related at all. With that command, you say to your compiler "shut up,
i know what I am doing"
 

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,990
Messages
2,570,211
Members
46,796
Latest member
SteveBreed

Latest Threads

Top