SFML community forums

Help => General => Topic started by: Spirrwell on October 25, 2015, 05:49:54 am

Title: Crash on Exit Passing RenderWindow to Class
Post by: Spirrwell on October 25, 2015, 05:49:54 am
Hi there!

I've researched this issue and tried various things learning that the RenderWindow is non-copyable and all that fun stuff. But, I swear I see other programs doing this that don't have an issue, which I'm guessing I'm simply missing a step.

At the moment, I'm running under Debug mode with the debug libraries linked statically. Basically I have a Camera class with a function DrawHUD that works like so:

void Camera::DrawHUD(sf::RenderWindow &window)
{
        testText.setString("Hi! I'm a HUD!");
        window.pushGLStates();
        window.draw(testText);
        window.popGLStates();
}

Basically it all comes down to window.draw() is where it ultimately crashes. Well, that's sort of true, because it only crashes when the program exits, but only if that draw() is called from inside my class.

When it crashes it goes to the file crtexe.c and points to the lines here:

            if (has_cctor == 0)
                _cexit();

and then proceeds to give me the Unhandled Exception error with ntdll.dll.

It doesn't matter if I pass it as a pointer, and I can't pass it directly because RenderWindow is noncopyable to avoid duplicate windows. So am I just stupid, or?

For more code context, this is basically how it works:

Camera mainCamera;
//...
//WHILE LOOP HERE
mainCamera.DrawHUD(window);

Any ideas? By the way, that testText thing has all the other stuff setup in the class' constructor, but where I put that seemed to not make any difference anyway.
Title: Re: Crash on Exit Passing RenderWindow to Class
Post by: mkalex777 on October 25, 2015, 07:10:30 am
I remember similar issue on windows xp with csfml 2.2, but it seems that it was fixed in 2.3
Title: Re: Crash on Exit Passing RenderWindow to Class
Post by: Gambit on October 25, 2015, 07:45:56 am
CSFML is not the official SFML library. It is a port/bind which may or may not do things the same way as the official SFML library (Ports/bindings usually introduce their own bugs, quirks and anomalies on top of the official code).

As for the problem: If I recall, SFML has problems when you close it .. I'm going to say incorrectly but thats not the right word.

I'm not sure if this is still an issue but I remember reading a while back (On here) that closing an SFML application by closing the console (For console apps), closes the application in a pretty ugly way.

I noticed you are pushing/poping GL states which CAN cause this problem if you close the application before your draw calls have been executed.
Title: Crash on Exit Passing RenderWindow to Class
Post by: eXpl0it3r on October 25, 2015, 07:52:33 am
You need to provide a minimal and compilable example.

My guess is that you have a normal window on the stack and just take the pointer to pass around but then let the window go out of scope when the application exits, but you're still somehow using the pointer of the non existing window anymore.

But without code all we can do is randomly guess.
Title: Re: Crash on Exit Passing RenderWindow to Class
Post by: zsbzsb on October 25, 2015, 12:49:33 pm
I remember similar issue on windows xp with csfml 2.2, but it seems that it was fixed in 2.3

There was no such thing, so unless you can start citing all of your insight please stop posting random pieces of 'information'.
Title: Re: Crash on Exit Passing RenderWindow to Class
Post by: Nexus on October 25, 2015, 01:25:23 pm
CSFML is not the official SFML library. It is a port/bind which may or may not do things the same way as the official SFML library (Ports/bindings usually introduce their own bugs, quirks and anomalies on top of the official code).
Yes, CSFML is one of the official bindings, together with SFML.NET. CSFML is supposed to behave like SFML unless explicitly otherwise noted -- we're glad if bugs or misbehaving features are reported.

There was no such thing, so unless you can start citing all of your insight please stop posting random pieces of 'information'.
I totally agree. Please don't spread rumors, it's not helpful in any way.
Title: Re: Crash on Exit Passing RenderWindow to Class
Post by: Spirrwell on October 25, 2015, 05:53:38 pm
I figured it out.

Ugh... Well to anybody else, basically I had an sf::Font declared globally, which I knew is a big "no-no" for creating Windows, but didn't realize that it also applied to other objects.

Moral of the story, don't make any SFML related classes global, ever, period.
Title: Re: Crash on Exit Passing RenderWindow to Class
Post by: Rosme on October 25, 2015, 11:05:24 pm
I'll go further. Don't ever make ANY global object. There is rarely a situation where it's valid.
Title: Re: Crash on Exit Passing RenderWindow to Class
Post by: Spirrwell on October 26, 2015, 12:59:03 am
I'll go further. Don't ever make ANY global object. There is rarely a situation where it's valid.
Tell that to the makers of Valve's Source Engine. Tons of globals there, that's kind of where I was getting some inspiration from. I've been programming under the Source Engine for quite a while now. But there's tons of global variables, externs all over the place, and whatnot.

Though it does kind of reek of C in terms of methodology. Anyway, I think globals are okay, but you have to base your program around what you have to work with I guess. Haven't messed with SDL in a while, but I could do the whole global variable thing there. Although I really like SFML with its more C++ feel.
Title: Re: Crash on Exit Passing RenderWindow to Class
Post by: Gambit on October 26, 2015, 04:23:21 am
The rule-of-thumb isnt "Dont ever use global variables", its more along the lines of "Be wary about the consequences of using them". Order of initialization isnt defined for global objects, even constants, so problems arise with certain types (Pretty much only user defined types) when declared globally.

The programmers at Valve know what they are doing so I'd say its safe to give them a bit of an exception here  :P
Title: Re: Crash on Exit Passing RenderWindow to Class
Post by: mkalex777 on October 26, 2015, 05:39:15 am
There was no such thing, so unless you can start citing all of your insight please stop posting random pieces of 'information'.
I totally agree. Please don't spread rumors, it's not helpful in any way.

So, if this is a feature of CSFML 2.2, then why it was removed in CSFML 2.3?

Here is an example on how to reproduce such interesting "rumored feature" of CSFML 2.2:
#include <SFML/Audio.h>

int main()
{
        sfSound* pSound = sfSound_create();
        if (!pSound) return 1;
        sfSound_destroy(pSound);
        return 0;
}
 

And here is "rumored feature" in action on Windows XP x32:
(http://savepic.su/6245045.png)
Title: Crash on Exit Passing RenderWindow to Class
Post by: eXpl0it3r on October 26, 2015, 07:21:20 am
It was a bug (not only for XP), it was fixed. But this has nothing to do with the topic so please stop posting here.
Title: Re: Crash on Exit Passing RenderWindow to Class
Post by: mkalex777 on October 26, 2015, 07:30:05 am
This has nothing to do with the topic so please stop posting here.

I has the same issue with CSFML 2.2 - the application was crashed on window close.

zsbzsb wrote that there is no such issue on CSFML 2.2.
Nexus totaly approved that there is no such issues and it's just a "rumors".

So, I posted the minimal code to reproduce "non-existing rumored issue". And added screenshot. That's is :)

It may be related with topic starter issue and may not be related. But it's definitely very similar issue. Because it happens on app close. And it's not so obvious that it may be caused by audio library. So I think it should be mentioned.
Title: Re: Crash on Exit Passing RenderWindow to Class
Post by: mkalex777 on October 26, 2015, 07:45:17 am
It was a bug (not only for XP), it was fixed.

I reproduced it on XP. It works ok on windows 7 and windows 10
Title: Re: Crash on Exit Passing RenderWindow to Class
Post by: Nexus on October 26, 2015, 08:30:42 am
Tell that to the makers of Valve's Source Engine. Tons of globals there, that's kind of where I was getting some inspiration from. I've been programming under the Source Engine for quite a while now. But there's tons of global variables, externs all over the place, and whatnot.
The programmers at Valve know what they are doing so I'd say its safe to give them a bit of an exception here  :P
Typical fallacy: argument from authority (https://en.wikipedia.org/wiki/Argument_from_authority)

The fact that one big company does something may be the result of various reasons, including historical or political ones -- in short, you don't know the backgrounds. Assuming that it's purely because of better design is risky, and applying the same reasoning to your own code, which has completely different preconditions, is a mistake.

This from a purely logical standpoint. There are objective arguments why global variables are problematic if used too often, see for example here (http://en.sfml-dev.org/forums/index.php?topic=5187.msg34227#msg34227). Please inform yourself carefully and be skeptic what you hear, instead of just thinking "ah, the big guys do it, so it must be right". Most progress in C++ during the decade of C++98 has been made by guys who questioned the common old ways of doing things -- and that was a huge step forward, considering that the language hasn't changed at all until 2011.

Tip: in C++, it's usually better to look at how people don't do things ;)

It may be related with topic starter issue and may not be related.
Because of that it would have been nice to open a different thread and post a link here, so the original discussion can go on uninterrupted. Don't open a thread now -- but thanks for reproducing the issue :)
Title: Re: Crash on Exit Passing RenderWindow to Class
Post by: mkalex777 on October 26, 2015, 10:31:14 am
Global variables makes spagetti code, you will not be able to reuse it and it will be hard to split the code on smaller parts. Also it makes big troubles with multithreading.

By the way, as I remember, there is no way to implement thread safe initializer for global variables with old c++ standard compiller. Does new c++ standard provides the way to do it?
Title: Re: Crash on Exit Passing RenderWindow to Class
Post by: Gambit on October 26, 2015, 11:40:22 am
Tell that to the makers of Valve's Source Engine. Tons of globals there, that's kind of where I was getting some inspiration from. I've been programming under the Source Engine for quite a while now. But there's tons of global variables, externs all over the place, and whatnot.
The programmers at Valve know what they are doing so I'd say its safe to give them a bit of an exception here  :P
Typical fallacy: argument from authority (https://en.wikipedia.org/wiki/Argument_from_authority)

The fact that one big company does something may be the result of various reasons, including historical or political ones -- in short, you don't know the backgrounds. Assuming that it's purely because of better design is risky, and applying the same reasoning to your own code, which has completely different preconditions, is a mistake.

This from a purely logical standpoint. There are objective arguments why global variables are problematic if used too often, see for example here (http://en.sfml-dev.org/forums/index.php?topic=5187.msg34227#msg34227). Please inform yourself carefully and be skeptic what you hear, instead of just thinking "ah, the big guys do it, so it must be right". Most progress in C++ during the decade of C++98 has been made by guys who questioned the common old ways of doing things -- and that was a huge step forward, considering that the language hasn't changed at all until 2011.

Tip: in C++, it's usually better to look at how people don't do things ;)sion can go on uninterrupted. Don't open a thread now -- but thanks for reproducing the issue :)

While I agree with you whole heartedly I'd still like to make the point that global variables are strongly discourages BUT that doesnt mean you cant/shouldnt use them ever, just use them with caution.
Title: Re: Crash on Exit Passing RenderWindow to Class
Post by: Satus on October 26, 2015, 12:55:56 pm
While I agree with you whole heartedly I'd still like to make the point that global variables are strongly discourages BUT that doesnt mean you cant/shouldnt use them ever, just use them with caution.

Instead of using them with caution, it is way better and easier to just not use them at all since you probably will never need them anyway.
Title: Re: Crash on Exit Passing RenderWindow to Class
Post by: shadowmouse on October 26, 2015, 01:11:25 pm
I would have thought "use them only if you have a logical and valid reason to use them" would be the best version of the advise. As it is with most other things that people use that they generally shouldn't. If they can justify why they use them and that justification is logically sound, then fine, let them use them.
Title: Re: Crash on Exit Passing RenderWindow to Class
Post by: mkalex777 on October 26, 2015, 03:18:07 pm
I'm sometimes using it for variables which have no sense to instantiate several times, for example - read only per application dictionary which.
Title: Re: Crash on Exit Passing RenderWindow to Class
Post by: Spirrwell on October 26, 2015, 06:15:35 pm
Wow, I never expected to come back here and see a full blown debate about the use of global variables. I apologize for kind of deferring from the original topic.

Tell that to the makers of Valve's Source Engine. Tons of globals there, that's kind of where I was getting some inspiration from. I've been programming under the Source Engine for quite a while now. But there's tons of global variables, externs all over the place, and whatnot.
The programmers at Valve know what they are doing so I'd say its safe to give them a bit of an exception here  :P
Typical fallacy: argument from authority (https://en.wikipedia.org/wiki/Argument_from_authority)

The fact that one big company does something may be the result of various reasons, including historical or political ones -- in short, you don't know the backgrounds. Assuming that it's purely because of better design is risky, and applying the same reasoning to your own code, which has completely different preconditions, is a mistake.

This from a purely logical standpoint. There are objective arguments why global variables are problematic if used too often, see for example here (http://en.sfml-dev.org/forums/index.php?topic=5187.msg34227#msg34227). Please inform yourself carefully and be skeptic what you hear, instead of just thinking "ah, the big guys do it, so it must be right". Most progress in C++ during the decade of C++98 has been made by guys who questioned the common old ways of doing things -- and that was a huge step forward, considering that the language hasn't changed at all until 2011.

Tip: in C++, it's usually better to look at how people don't do things ;)

It may be related with topic starter issue and may not be related.
Because of that it would have been nice to open a different thread and post a link here, so the original discussion can go on uninterrupted. Don't open a thread now -- but thanks for reproducing the issue :)

Oh I was never defending what they do, by God I hate the Source engine, yet I now program with it almost every day. I hate it, I hate it, I hate it. Also the Source engine was built off of old Quake engines and whatnot. I just find it interesting that programming under this for so long has influenced my coding style. I don't think I ever made a single global variable when coding under Unity, but that's C# not C++.

Agh, I'm doing it again. Sorry for the off topic rant, feel free to lock the topic, I just really get into these types of discussion, even if it is off topic.