C++ virtual methods

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
znewsham
Posts: 9
Joined: Sat Sep 01, 2007 6:16 am

C++ virtual methods

Post by znewsham »

OK, I have been having some fun writing my own OS for some months, I started in ASM, and soon decided that it was not going to be right for me, so I changed to C++, I chose C++ over C as I like the object Oriented aproach to programming, Anyways, I have implemented things such as new, delete, and the funky __cxa__virtual() thingy, however I still cant get virtual functions to work, either nothing happens or the PC/bochs crashes.

Here is the setup:

I have 3 classes (that are involved in this)

CFile, CFAT, CFAT12 (CFAT16 and CFAT32 to follow)

CFile consists of:

Code: Select all

#include "CFAT.h"
class CFile
{
private:
CFAT * mpFAT;
public:
CFile(CString * pFileName)
{
 //this bits pseudo
 if (pFileName[0]=="A") //floppy
 {
  mpFAT = new CFAT12(pFileName,0);
 }
}
Open()
{
mpFAT->Open();
}
};
CFAT consists of:

Code: Select all

class CFAT
{
public:
CFAT(CString * pFileName, int drive)
{

}
virtual int getNextCluster(int cluster)=0;
Open()
{
 //do open file type stuff
 while (nextCluster!=last)
 {
  nextCluster=getNextCluster(nextCluster);
 }
}
};
CFAT12 consits of:

Code: Select all

#include "CFAT.h"
class CFAT12 : public CFAT
{
public
CFAT12(CString * pFileName, int drive) : CFAT (pFileName, drive)
{

}
int getNextCluster(int cluster)
{

}
};
now I have tried the file open method with all the code inside CFAT, and no CFAT12, and it works, so there is nothing wrong with that, but I need the specifics (namely getting next cluster) to be for each of the FAT types, and as I say it either crashes, or does nothing, I have tried a simpler example, just with a CShape and a CSquare, and it crashes.

Any Ideas?

Thanks

Zack.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Hi,

How does it crash? Are you absolutely convinced that your 'new' operator works nicely - it's not a case of allocating memory twice, or something like that? When Bochs crashes, are E/RSP and E/RIP where your would expect them to be? Is there a page fault value in CR2? Have you filled the variable 'last' correctly (is nextCluster!=last always evaluating true?).

Sorry to answer your question with questions, but I can't immediately see anything wrong with your use of the virtual function and this works OK in my OS without any support code (I don't even have __cxa__virtual() - I think this is only needed when the compiler can't find the actual function).

Oh - I've just seen, why do you set the virtual function to zero? This isn't something I've seen before (that's not to say it isn't perfectly valid...sorry for the double negative!).

Cheers,
Adam
User avatar
B.E
Member
Member
Posts: 275
Joined: Sat Oct 21, 2006 5:29 pm
Location: Brisbane Australia
Contact:

Post by B.E »

AJ wrote:Why do you set the virtual function to zero?
This is similar to abstract in java. The function doesn't need a proper definition, also you can't instantiate the class and you must declare it in subclasses.
Last edited by B.E on Tue Jan 15, 2008 2:53 am, edited 1 time in total.
Image
Microsoft: "let everyone run after us. We'll just INNOV~1"
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Try making the function not pure virtual - i.e. removing the =0 and adding a stub {...}. See if that works. If it does, you're accessing the pure virtual function and your _cxa__virtual function is ballsed up.
znewsham
Posts: 9
Joined: Sat Sep 01, 2007 6:16 am

Post by znewsham »

I have tried using a non pure virtual method

I even tried using a really simple example, 2 classes, one CShapes, one CSquare, and doing a similar method, the code works in windows, but does not work when I try to use it,

I dont know what a page fault looks like, but I do not use paging, I use a flat memory model.

The new operator definatly works, as I use it for lots of other stuff as well.

When it crashes, bochs simply restarts, I am not sure what CS or IP should be, so I cant really check that.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

znewsham wrote:When it crashes, bochs simply restarts, I am not sure what CS or IP should be, so I cant really check that.
Perhaps this would be a good point to implement a proper fault handling in your OS, one that prints some sort of register dump?
Every good solution is obvious once you've found it.
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

I suggest mapping "INT 0x3" (debug interrupt) to print out a register dump and halt.
Cemre
Member
Member
Posts: 31
Joined: Fri Nov 09, 2007 5:25 am

Post by Cemre »

you have to implement the "type_info" ( googling will help ) class with a virtual destructor "std::type_info::~type_info()"

and you have to derive "__class_type_info" "__fundamental_type_info" ( and several other [again :) google] ) classes from this "std::type_info" class, otherwise virtual functions wont work, that is, to emit the virtual tables, gcc needs those "__class_type_info" classes. and gcc emits the virtual tables only on the object file where the ( virtual ) destructor of the class is implemented. that is also why it would be a good idea to implement a virtual destructor for every class that has virtual methods. otherwise gcc complains a lot.

if those classes are not found, virtual tables will not be emitted or will be emitted with null virtual function pointers, and that will eventually lead to a crash.
Last edited by Cemre on Wed Jan 16, 2008 5:23 am, edited 1 time in total.
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Cemre wrote:you have to implement the "type_info" ( googling will help ) class with a virtual destructor "std::type_info::~type_info()"

and you have to derive "__class_type_info" "__fundamental_type_info" ( and several other [again :) google] ) classes from this "std::type_info" class, otherwise virtual functions wont work, that is, to emit the virtual tables, gcc needs those "__class_type_info" classes. and gcc emits the virtual tables only on the object file where the ( virtual ) destructor of the class is implemented. that is also why it would be a good idea to implement a virtual destructor for every class that has virtual methods. otherwise gcc complains a lot.
Not true. My kernel uses virtual functions and doesn't require those classes.
Cemre
Member
Member
Posts: 31
Joined: Fri Nov 09, 2007 5:25 am

Post by Cemre »

JamesM wrote: Not true. My kernel uses virtual functions and doesn't require those classes.
may be a difference in gcc versions,
my kernel doesn't link without those classes.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Same here - no problems with virtual functions in my OS.

@Cemre: Are those classes perhaps to do with RTTI support? (just a guess - I haven't got this in my OS yet).

Cheers,
Adam
Cemre
Member
Member
Posts: 31
Joined: Fri Nov 09, 2007 5:25 am

Post by Cemre »

AJ wrote: @Cemre: Are those classes perhaps to do with RTTI support?
exactly, gcc puts the pointer of "run time type information object" of the that class to its virtual table. ( an object of class __class_type_info )

even if I disable rtti with "-fno-rtti", in my gcc version, i continue to get links related to constructor and destructor of those classes

"__class_type_info::__class_type_info()" "__class_type_info::~__class_type_info()"
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

I don't. -fno-rtti disables everything for me. Perhaps you need to disable exceptions as well?
znewsham
Posts: 9
Joined: Sat Sep 01, 2007 6:16 am

Post by znewsham »

I suggest mapping "INT 0x3" (debug interrupt) to print out a register dump and halt.
I will get on that now, is there anything in particular that I should be looking for?
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Call it when you want to check the values of registers. It's very useful.
Post Reply