C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

virtual & casting

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++)
View previous topic :: View next topic  
Author Message
Alex Vinokur
Guest





PostPosted: Tue Nov 21, 2006 10:10 am    Post subject: virtual & casting Reply with quote



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[i];
}
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[i];
}
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[i];
}
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 = Cool : qwertyu1
pch2 (buf-size = Cool : ₪!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
Back to top
ondra.holub
Guest





PostPosted: Tue Nov 21, 2006 10:11 am    Post subject: Re: virtual & casting Reply with quote



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.
Back to top
VJ
Guest





PostPosted: Tue Nov 21, 2006 10:11 am    Post subject: Re: virtual & casting Reply with quote



Alex Vinokur wrote:
Quote:
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.


Quote:
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"
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.