Page 1 of 3
Constructors not called ???
Posted: Mon May 18, 2009 8:34 am
by quanganht
Can anyone help me find out why does the constructor of the class CConsole not run?
But the code below will run flawlessly
Code: Select all
int test::i;
class test
{
private:
int i;
public:
test();
~test();
int ret();
};
test::test()
{
i=100;
}
test::~test(){}
test::ret()
{ return i }
then ret() still return 100. That means the constructor was called. BTW, why do I *MUST* have the "int test::i" ???
(Gcc will pop errs if that line not presents).
Edit: Oh hell no. That code doesn't work now ( just used to ). Anyway, help me!
Re: Constructors not called ???
Posted: Mon May 18, 2009 8:40 am
by yemista
I think it has something to do with the fact that your using C++ to develop an OS with no standard libraries available.
Re: Constructors not called ???
Posted: Mon May 18, 2009 8:49 am
by quanganht
I know. So what's the deal?
Re: Constructors not called ???
Posted: Mon May 18, 2009 8:56 am
by Combuster
C++ most common errors #1:
Code: Select all
class apple
{
pear X;
orange Y;
}; // MISSING SEMICOLON!!!1!1one!
Man even I make that one every other time
Re: Constructors not called ???
Posted: Mon May 18, 2009 9:01 am
by quanganht
Since it can be compiled, then there is no syntax errors.
It just not run the right way.
Re: Constructors not called ???
Posted: Mon May 18, 2009 9:12 am
by kraks
How do you declare the instance-variable(s) of class "test"? I hope you don't expect malloc to call the constructor?
Re: Constructors not called ???
Posted: Mon May 18, 2009 9:19 am
by quanganht
kraks wrote:How do you declare the instance-variable(s) of class "test"? I hope you don't expect malloc to call the constructor?
No. Why? The constructor are suppose to be called before the kmain()
Re: Constructors not called ???
Posted: Mon May 18, 2009 10:00 am
by Solar
yemista wrote:I think it has something to do with the fact that your using C++ to develop an OS with no standard libraries available.
Since he doesn't use any standard library code, that wouldn't matter much, now would it?
kraks wrote:How do you declare the instance-variable(s) of class "test"? I hope you don't expect malloc to call the constructor?
1) If anything, it'd be new, not malloc.
2) new doesn't have anything to do with initializing member variables.
So let's start at the beginning. You tell us the constructor is not called. How did you make sure that this is, indeed, the case? (I am assuming that you made 100% sure that it's actually a fact, but I'd like to hear it from you instead of trying to figure it out myself.)
Edit: My GCC chokes on files not ending with a newline...
Re: Constructors not called ???
Posted: Mon May 18, 2009 10:38 am
by neon
quanganht wrote:I know. So what's the deal?
If you dont have a standard runtime library (of sorts) to call the ctors they wont be called. (In most [if not all] cases; I suspect GCC is the same though). Do you have a runtime that calls the ctors? Have they been getting called in the past without error?
Re: Constructors not called ???
Posted: Mon May 18, 2009 10:50 am
by yemista
Well I remember reading about similar problems on this forum before. Doesnt it have something to do with the fact that c++ uses objects, and when you create a new object, you have to allocate space for it, and since there are no standard libraries available, the functions that allocate the space for it are not available, so you run into problems?
Re: Constructors not called ???
Posted: Mon May 18, 2009 11:11 am
by JamesM
Hi,
OK, seeing as noone has posted the actual answer to your problem yet, I might as well.
http://wiki.osdev.org/C_PlusPlus#Global_objects
Although really I don't think the explanation there is fantastic, so I'll provide a brief summary here.
Global objects are normally initialised before the main function is called. This is done by the host operating system and is invisible to end-users (end users here being the C++ programmer).
You don't have a host OS, so you must do this yourself, else obviously your constructors won't be called.
The compiler (assuming GCC) emits special sections containing an array of function pointers. These are located in the .ctors and .dtors sections (for constructors and destructors) - add a line in your linker script that exports the location of these sections as symbols, then extern that symbol in your main initialisation code and run through the array, calling each in turn as a function with no return value and no arguments, thus:
Code: Select all
extern int start_ctors;
extern int end_ctors;
size_t i;
for (i = (size_t)&start_ctors; i < (size_t)&end_ctors; i++)
{
void (*fn)() = (void (*)())i;
fn();
}
Cheers,
James
Re: Constructors not called ???
Posted: Mon May 18, 2009 12:32 pm
by kraks
quanganht wrote:kraks wrote:How do you declare the instance-variable(s) of class "test"? I hope you don't expect malloc to call the constructor?
No. Why? The constructor are suppose to be called before the kmain()
Depends on where you declare the variable. If it's declared in function-scope, the constructor get's called inside the function; and that's how it is in your code. So it's propably
not an error with the global-constructors-thingy (except the gcc "outsourced" the variable which it isn't actually allowed to). How do you check whether the constructor gets called? Maybe you could put "console.clrscr();" and "console.write("Constructor called\n");" inside the constructor and enter an endless loop after the variable is declared in kmain.
solar wrote:1) If anything, it'd be new, not malloc.
I thought (before having a quick glance at the code) that he might have coded
Code: Select all
CConsole* cons = (CConsole*) kmalloc( sizeof(CConsole) );
and expected the constructor to be called.
solar wrote:2) new doesn't have anything to do with initializing member variables.
Huh? It calls the constructor which then constructs the auto-var-members. Of course, PODs have to be explicitely constructed
Re: Constructors not called ???
Posted: Mon May 18, 2009 5:44 pm
by quanganht
@James
Of course I called the constructors before the main kernel. take a look at support.c
But seems like I need something else:
Code: Select all
int __cxa_atexit(void (* f)(void *), void *p, void *d);
void __cxa_finalize(void *d);
@Solar
Solar wrote:
So let's start at the beginning. You tell us the constructor is not called. How did you make sure that this is, indeed, the case? (I am assuming that you made 100% sure that it's actually a fact, but I'd like to hear it from you instead of trying to figure it out myself.)
Simple. There is a line "clrscr()" that will clear the screen inside the constructor. If the screen not cleared then it haven't been called.
EDIT: Hey, what about implementing NEW and then:
Code: Select all
CConsole console = new CConsole();
Re: Constructors not called ???
Posted: Mon May 18, 2009 6:21 pm
by frank
quanganht wrote:EDIT: Hey, what about implementing NEW and then:
Code: Select all
CConsole console = new CConsole();
If you rewrote that as
Code: Select all
CConsole *console = new CConsole();
then it should work fine. The constructor should be called manually by the compiler right after the call to new completes.
Re: Constructors not called ???
Posted: Tue May 19, 2009 6:31 am
by fieldofcows
quanganht wrote: BTW, why do I *MUST* have the "int test::i" ???
(Gcc will pop errs if that line not presents).
You only have to include that line if you declare the variable as "static" within your class declaration (like you have with the variables in your CConsole class).
I've just taken a look at your CConsole constructor and noticed two things:
1) Your constructor does not seem to call clrscr() like you mentioned in your post.
2) The vram variable is set to 0x8B00. Shouldn't this be 0xB8000?
Does the screen clear correctly if you call clrscr() after your class is constructed, i.e. outside of the constructor?