Skip to main content
GameDev.net gamedev.net
🔒 Locked

class constructor not called [EDITED]

Started by janta Feb 8, 2006 at 8:05 AM 17 replies 1.7k views
Original Post
janta
janta
EDITED OK now the actual problem is not what I thought (that a constructor was not called, it indeed was but agressive inlining and optimizing let me believe it was not...) For some reason, every object that is created as a global object (something like a declaration of
MyObject object;
seems to cause a crash during initialisation of the game (that is, even before WinMain is called) I added further detail in my other posts below, please read the whole topic if you feel like helping me. Thanks a lot :) [Edited by - janta on February 8, 2006 3:25:42 PM]
Big_Bear_Scot
Big_Bear_Scot
try putting

public:

before the constructor in the .h file. SO your code in savegamemanager.h will be

// *** In savegamemanager.h ***class SaveGameManager{public:SaveGameManager();// other stuff}


Let me know if it works, also if you derive a new class from SaveGameManagerWin32 you will need to declare that as public also.

By default if you don't declare access to a function or a variable in class it is declared as private, this means that the function can only be accessed inside that class.

Have a little look at this link for a decent explanation
janta
janta
Quote:
Original post by Big_Bear_Scot
try putting

public:

before the constructor in the .h file. SO your code in savegamemanager.h will be

// *** In savegamemanager.h ***class SaveGameManager{public:SaveGameManager();// other stuff}


my apologies for not mentionning it but both classes' structors are indeed declared as public. Thank you for trying, though ;)
I'm presently still trying to understand that behaviour, and if I find any clue, I'll let you know.
janta
janta
Here comes another clue.

Both constructors are called if I switch to a Debug configuration, and my program will not crash then.

But in Release config, only the base class constructor is called, and I end up with a "illegal instruction" failure when _initterm function is called (the first or second call before WinMain) I'm not sure this is related, though I belive it somehow is...

Anyway, I have investigated visual c++ (2003) compiling and linking options but didn't achive satisfying results yet, despite deactivating all compiler and linker optimisations.

Also, the program doesn't crash on a Athlon 64 (but the constructor's still not called) but it does crash with my Athlon 800mhz.

Stay tunned and thanks to people who try ton co-investigate this problem with me :)
joltios
joltios
// *** in savegamemanager.cpp ***




SaveGameManager::SaveGameManager()// you need to tell which class you are using


{


*breakpoint 1* DoSomeStuff();


}

same with

// *** in savegamemanagerwin32.cpp ***


SaveGameManagerWin32::SaveGameManagerWin32()


{


*breakpoint 2* DoSomeStuffForWin32();


}

janta
janta
Arghhh sorry for all these mistakes, I hastefully copied the principles of my code here without paying attention to it's exactitude.
Please assume my code is free from such trivial errors. As I mentionned before, everythings works fine in Debug configuration, but does not in Release Configuration.

Also, if in ** Realease ** config i write sth like.

SaveGameManagerWin32* pmanager = new SaveGameManagerWin32 ();


both constructors are called. Hence I really believe the problem is somehow related to window's obsure initialization routines of statically declared objects (which is not the cleanest way to do some stuff but in fact this is a code I must work on, not that I wrote myself)

thanks however
Red Ant
Red Ant
I would say that it is more than likely a bug in your code rather than any dodgyness in Window's initialization routines.

And in the future, when posting code, please use the source tag to make it more readable. Just to be 100 percent sure you haven't made any mistakes while typing your code up on the message board, can you please copy&paste your stuff directly from your project into the forum (and use those source tags please!) and then just strip out anything that isn't strictly relevant to the problem?
Dolphin
Dolphin
I have the following guesses for your problem:

1. The 2nd constructor seems not to get called in Release mode, because of the optimization that is done in a Release Build. For example when the code is optimized in such a way that the two constructors are but together in one function , then the generated code is mixed up and the Debugger doesn't know how to break at the specific line you set the breakpoint. To check this out you could for example display a MessageBox in each constructor. If both are shown in Debug and Release then you know that everything is ok.

2. The program / game might crash in Release-Mode only because of a memory leak / array access problem. I had those errors several times. In Debug-Mode everything seems to work, but this is only due to the fact that in Debug-Mode other memory allocation routines are used. Those put some "guard bytes" around the allocated memory. So if you are of by one or something, this error possibly won't crash you application in a Debug-Build, but will do so in a Release-Build.

If we could see your real code (perhaps even compile on ourselves) we probably could help you much better. Hope my guesses are of any help to you ;)
dbzprogrammer
dbzprogrammer
I'm not too sure what the problem, but something is making me think that if you add a initializer list to the end of the constructor for the child class, you might get some more posisitve results. And when you throw an object on the stack that's inherited, I believe you simply use the base class's constructor. I could be wrong on that though. Here's what I'm thinking:

// *** in savegamemanagerwin32.h ***class SaveGameManagerWin32 : public SaveGameManager{public:SaveGameManagerWin32();// other stuff}// *** in savegamemanagerwin32.cpp ***SaveGameManager::SaveGameManagerWin32() : SaveGameManager(){*breakpoint 2* DoSomeStuffForWin32();}


That's it, see if it works...
We should do this the Microsoft way: "WAHOOOO!!! IT COMPILES! SHIP IT!"
dbzprogrammer
dbzprogrammer
#include "stdafx.h"#include <iostream>using namespace std;class A{public:	A()	{	cout << "Class A called." << endl;	}};class B : public A{public:	B()	{	cout << "Class B called." << endl;	}};void main(){	B bobj;}


Getting no errors here, I don't know what's going on dude...
We should do this the Microsoft way: "WAHOOOO!!! IT COMPILES! SHIP IT!"
janta
janta
Indeed very usefull, Dolphin :)

In fact, I gave up investigating on why the constructor was not called, assuming something similar to what you described would probably be done by the linker (since a constructor not being called sounds like heretic to me :p) Also, I gave up because after removing that particular object (_saveGameManagerWin32) I realized that the same crash would occur with any other global object

That's why I turned my investigations to the compiler/linker options. When I run the program in debug mode, it crashes at, like I said before, during the call to _initterm function, which is part of initialization routines. That functions receives a list of function pointers and executes all of them one after each other. The exact code is as follows:

static void _cdecl _initterm( _PVFV * pfbegin, _PVFV * pfend){    while(pfbegin < pfend)    {        if(*pfbegin != NULL)            (**pfbegin)();        plus_plus pfbegin; // Crash here    }}


(why wont the "plus plus" operator display ?)

For some reason, the
plus_plus pfbegin;
instruction crashes after n iteration (I mean, not the first iteration)

About the original source code, I cannot copy it here since it is copyrighted material. Still, I believe that it wou8ld not be very usefull for me to give you the whole project, being about 1.5 Millions lines of code...

What I'm doing now is I have created a new configuration based on Debug and step by step turn it into a release configuration. I have already enabled all optimization et deactivated all debug info and the game hasn't crashed so far...

Stay tunned ! :)
janta
janta
>> dbz programmer

I tried this this mornig too but it gave no result. As dolphin said, it is more than likely that visual c++ provides me with some dark-side-optimization :D and I now believe that this constructor trouble is in fact not a problem and not related to my real problem :)

Thaks for your concern though.
starmole
starmole
There is only one reason because the constructor of a class would not
be called - an exception happened in a base constructor or in a constructor
of a member. So you can only verify


  • whether a break point at the end of the constructor of the base class
    is hit
  • if you create a dummy class with a constructor having a break point,
    and add it as member to the derived class, you may find a similar
    problem if it is in a constructor of a member of the derived class.


Otherwise I can only suggest single stepping and verifying until you see
something that is suspicious to you in the debugger ...
janta
janta
Quote:
Original post by Anonymous Poster
Are you sure the constructors are actually not being called? For example, if you put a printf or something into the constructor to check? The reason I ask is that sometimes the aggressive inlining and optimising the compiler does can confuse the debugger.


>> Indeed, just what was said a few posts before yours dude :)
You can as well consider this problem as solved. Maybe I should start a new topic for my real problem, for the title of this one is a bit confusing.
dbzprogrammer
dbzprogrammer
Quote:
Original post by janta
>> dbz programmer

I tried this this mornig too but it gave no result. As dolphin said, it is more than likely that visual c++ provides me with some dark-side-optimization :D and I now believe that this constructor trouble is in fact not a problem and not related to my real problem :)

Thaks for your concern though.


Alright, I want to see where this leads too! =D
We should do this the Microsoft way: "WAHOOOO!!! IT COMPILES! SHIP IT!"
janta
janta
Most important: the problem occurs only on PIII / Athlon machines. PIV, Athlon XP and 64 run perfectly. The assembler code points out a "movaps" assembler instruction, which I believe is part of SSE instruction set. Althoug these where disabled in this project, some of the librairies that I link to might be responsible for that instruction.

By the way, sorry for all those weird troubles i'm bringing here ;)
Stay tunned
janta
janta
OK do you want the final word ? :) Well I assume you do :P

In fact (shame on me...) the linker linked to a xbox librairy instead of win32 librairy, which would not be any troublesome on our Athlon 64 / Pentium IV developping machines, and thats why nobody on the team ever noticed this configuration bug.

But my Pentium III obviously did (not like SSE instructions used in xbox libraires)

The end =D
Dolphin
Dolphin
well, at least an explanation ;)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.