Tricky C++ question
-
DarylD
Tricky C++ question
Okay, a question for those of you who know.
I am writing my API library in C++ (works well so far), but one thing I am stuck on is this:
I have a class called console with a constructor. I have my own created c++ new operator defined as follows:
void *operator new ( size_t nBytes ) which will call my kernel malloc function (I don't have a problem with this).
Looking at the disassembly all seems fine, but it won't call the constructor for my class when it does the new and I am not sure why, I thought this was a built-in C++ thing.
Can anyone help?
I am writing my API library in C++ (works well so far), but one thing I am stuck on is this:
I have a class called console with a constructor. I have my own created c++ new operator defined as follows:
void *operator new ( size_t nBytes ) which will call my kernel malloc function (I don't have a problem with this).
Looking at the disassembly all seems fine, but it won't call the constructor for my class when it does the new and I am not sure why, I thought this was a built-in C++ thing.
Can anyone help?
- Pype.Clicker
- Member

- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
-
_mark()
Re:Tricky C++ question
You should create a "placement new"
void *operator new( size_t, void * )
the new you created does not have a "this" pointer - thus it cannot call the constructor.
Mark
void *operator new( size_t, void * )
the new you created does not have a "this" pointer - thus it cannot call the constructor.
Mark
-
_mark()
Re:Tricky C++ question
Sorry - I'm not sure what I was thinking. Ignor anything I say before 9am. 
This is a built in C++ thing, the "new" operator (not operator new) should compile down to two calls. You said this looks fine when disassembled? You should see something like:
call operator new ( some_size )
; a few other things....
call console::console ( add_of_this )
If you see this, then your constructor may be defined
incorrect and the compiler is calling a "default" constructor that it is creating for you.
Mark
This is a built in C++ thing, the "new" operator (not operator new) should compile down to two calls. You said this looks fine when disassembled? You should see something like:
call operator new ( some_size )
; a few other things....
call console::console ( add_of_this )
If you see this, then your constructor may be defined
incorrect and the compiler is calling a "default" constructor that it is creating for you.
Mark
-
DarylD
Re:Tricky C++ question
I don't get the console::console part. I get the part which calls malloc (well, my placeholder anyway) it just never seems to go on to call the constructor.
Sure its something obvious but I admit I am not a C++ guru by any stretch.
Sure its something obvious but I admit I am not a C++ guru by any stretch.
-
_mark
Re:Tricky C++ question
The following code:
compiles to:
If both new and the constructor were defined incorrect - you would see:
It is probably something small your overlooking - post the code and we might be able to help more.
Mark
Code: Select all
#include <stdio.h>
#include <malloc.h>
class foo1
{
public:
int ggg;
void *operator new( size_t s )
{
return( malloc( s ) );
}
foo1()
{
printf("foo1() called\n");
}
};
main()
{
foo1 *f = new foo1;
return 1;
}
Code: Select all
>> 21: main()
>> 22: {
00401030 push ebp
00401031 mov ebp,esp
00401033 push 0FFh
00401035 push offset __ehhandler$_main (0041327b)
0040103A mov eax,fs:[00000000]
00401040 push eax
00401041 mov dword ptr fs:[0],esp
00401048 sub esp,50h
0040104B push ebx
0040104C push esi
0040104D push edi
0040104E lea edi,[ebp-5Ch]
00401051 mov ecx,14h
00401056 mov eax,0CCCCCCCCh
0040105B rep stos dword ptr [edi]
>> 23: foo1 *f = new foo1; // NOTE: call to foo1::new
0040105D push 4
0040105F call @ILT+10(foo1::operator new) (0040100f)
00401064 add esp,4
00401067 mov dword ptr [ebp-18h],eax
0040106A mov dword ptr [ebp-4],0
00401071 cmp dword ptr [ebp-18h],0
00401075 je main+54h (00401084)
00401077 mov ecx,dword ptr [ebp-18h]
>> // NOTE: call to foo1::foo1
0040107A call @ILT+0(foo1::foo1) (00401005)
0040107F mov dword ptr [ebp-1Ch],eax
00401082 jmp main+5Bh (0040108b)
00401084 mov dword ptr [ebp-1Ch],0
0040108B mov eax,dword ptr [ebp-1Ch]
0040108E mov dword ptr [ebp-14h],eax
00401091 mov dword ptr [ebp-4],0FFFFFFFFh
00401098 mov ecx,dword ptr [ebp-14h]
0040109B mov dword ptr [ebp-10h],ecx
>> 24: return 1;
0040109E mov eax,1
>> 25: }
Code: Select all
>> 21: main()
>> 22: {
00401030 push ebp
00401031 mov ebp,esp
00401033 sub esp,48h
00401036 push ebx
00401037 push esi
00401038 push edi
00401039 lea edi,[ebp-48h]
0040103C mov ecx,12h
00401041 mov eax,0CCCCCCCCh
00401046 rep stos dword ptr [edi]
23: foo1 *f = new foo1; // NOTE: call to global new
00401048 push 4
0040104A call operator new (004010c0)
0040104F add esp,4
00401052 mov dword ptr [ebp-8],eax
00401055 mov eax,dword ptr [ebp-8]
00401058 mov dword ptr [ebp-4],eax
24: return 1;
0040105B mov eax,1
NOTE: no constructor called:
25: }
Mark
-
DarylD
Re:Tricky C++ question
Cheers, sorted it now.
Jut got my ongoing problem with bloody PLT's in ELF, but don't worry I won't be asking for help with that, I will just wait until my brain implodes.
Daryl.
Jut got my ongoing problem with bloody PLT's in ELF, but don't worry I won't be asking for help with that, I will just wait until my brain implodes.
Daryl.
-
DarylD
Re:Tricky C++ question
No, I haven't got the problem sorted 
Remember, I have *NO* built in C++ functionality apart from the basic stuff as I have no libraries I can use, I need to create my own.
Basically what I need is a definition for new...
If i use a os::var a= new os::var(); inside a function it compiles correctly, but if I try and do it globally by defining it outside a function, the initialisation code is generated by g++ but it isn't actually called.
I.e. I have this big block of code in the disassembly but it is never called from anywhere...why??
Daryl.
Remember, I have *NO* built in C++ functionality apart from the basic stuff as I have no libraries I can use, I need to create my own.
Basically what I need is a definition for new...
If i use a os::var a= new os::var(); inside a function it compiles correctly, but if I try and do it globally by defining it outside a function, the initialisation code is generated by g++ but it isn't actually called.
I.e. I have this big block of code in the disassembly but it is never called from anywhere...why??
Daryl.
-
_mark
Re:Tricky C++ question
Ah - I see...
Depending on the compiler, there is a function called before main() and one called after main(). The call after main is usually called atexit() - it is responsible for calling the destructors of all globally instanciated objects. The routine you are looking for is very compiler dependant, but basically you can easily find it by creating a simple C++ app with a global object. Set a break point in the constructor and look at the call stack. In any case, this is the piece of the puzzle you are probably missing. The initialization code needs to call all global constructors BEFORE main() is entered. This is not to be confused with what
new(size) or new(size,void*) do. A global object exists in the stack - not the heap. And since it was placed in the stack prior to main(), something needs to go back and call the constructor. When writting an OS, you probably bypass all the normal CRT stuff, so you will have to provide this yourself.
I suggest you look at the source for the CRT and related libraries that came with your compiler for more details on how they did it.
This is not the last obsticle you will come accross using C++.
Good Luck.
Mark
Depending on the compiler, there is a function called before main() and one called after main(). The call after main is usually called atexit() - it is responsible for calling the destructors of all globally instanciated objects. The routine you are looking for is very compiler dependant, but basically you can easily find it by creating a simple C++ app with a global object. Set a break point in the constructor and look at the call stack. In any case, this is the piece of the puzzle you are probably missing. The initialization code needs to call all global constructors BEFORE main() is entered. This is not to be confused with what
new(size) or new(size,void*) do. A global object exists in the stack - not the heap. And since it was placed in the stack prior to main(), something needs to go back and call the constructor. When writting an OS, you probably bypass all the normal CRT stuff, so you will have to provide this yourself.
I suggest you look at the source for the CRT and related libraries that came with your compiler for more details on how they did it.
This is not the last obsticle you will come accross using C++.
Good Luck.
Mark
-
whyme_t
Re:Tricky C++ question
Not that I want to p1mp myself, but I've explained some of this in http://www.invalidsoftware.net/os/.
-
_mark
Re:Tricky C++ question
Looks like a descent totorial. How have you found writting an OS in C++ - I would think the cons far outway the pros??? What is your real experience?
Mark
Mark
-
whyme_t
Re:Tricky C++ question
The ever changing C++ Standard, and the non Standard implementation of different Compilers is Sickening. I used to enjoy C++, but the more I learn the internals and low level implementations, I see it being a bit of a 'pain in the @Ss'.
If you just want basic C++ in your OS, there is no problem. By using the support code on my site, and linking with the C++ support lib (libsupcxx.a in DJGPP), you can use global/static objects, and inheritance with no problems, as long as you disable RTTI and EH. It's only when you want polymorphism and some of the more advanced aspects of C++ that life becomes difficult.
All in all, I've had no problems interfacing asm and C++, writing ISR's, keyboard Drivers, low level memory management, etc, in C++ and ASM (I have even written member functions in pure asm) where necessary. If you want all the bells and whistles of C++, the bottom line is much much more frame work is needed. If you get it working, more power to you
If you just want to write an OS and focus on that, don't use C++. At least until somebody sometime standardises C++, and provides support of freestanding RTLs.
P. S. This has all lead to pskyboy and I creating a new Object Oriented language. I won't reveal any details now, but keep an eye out for future news.
If you just want basic C++ in your OS, there is no problem. By using the support code on my site, and linking with the C++ support lib (libsupcxx.a in DJGPP), you can use global/static objects, and inheritance with no problems, as long as you disable RTTI and EH. It's only when you want polymorphism and some of the more advanced aspects of C++ that life becomes difficult.
All in all, I've had no problems interfacing asm and C++, writing ISR's, keyboard Drivers, low level memory management, etc, in C++ and ASM (I have even written member functions in pure asm) where necessary. If you want all the bells and whistles of C++, the bottom line is much much more frame work is needed. If you get it working, more power to you
P. S. This has all lead to pskyboy and I creating a new Object Oriented language. I won't reveal any details now, but keep an eye out for future news.
-
DarylD
Re:Tricky C++ question
Thanks for all the help:
Whyme_t, does it matter that I am not using C++ for my kernel, only for the API library, will this have an impact on what you are suggesting?
Daryl.
PS. The tutorial is very useful.
Whyme_t, does it matter that I am not using C++ for my kernel, only for the API library, will this have an impact on what you are suggesting?
Daryl.
PS. The tutorial is very useful.
-
_mark
Re:Tricky C++ question
Yes - there is quite a bit of good info in the tutorial. Thanks for sharing it.
pskyboy mentioned the language in another post. I would be interested in seeing what you all have done since I have been thinking along those same lines.
Thanks
Mark
pskyboy mentioned the language in another post. I would be interested in seeing what you all have done since I have been thinking along those same lines.
Thanks
Mark