Shortcut to my Release .exe
Hey.
I've finished a small program that uses the console and a window (using SDL library). I want to be able to run that program by opening it's release .exe via a shortcut. When I open the .exe out of my IDE, it opens and then closes straight away. When I run (CTRL + F5) it in my IDE it works fine whether in debug or release mode. Just wondering what the problem is here and how I can get it to work.
P.S I know this type of issue has been discussed a lot but I couldn't find any posts that addressed my particular problem...
Cheers. :)
[581 byte] By [
Mybowlcut] at [2007-11-20 10:58:15]

# 1 Re: Shortcut to my Release .exe
That behavior is by design. To have it stopped you should either add a
system("pause");
at the end of main, or
getch();
cilu at 2007-11-9 1:24:54 >

# 2 Re: Shortcut to my Release .exe
... which many here (myself included) consider bad style. If you write a command-line program, you really should run it from the console.
Why we don't like it? If you insert a system("pause") at the end of main, this is not the same as a pause at the end of your program. Your print-out may be incomplete.
treuss posted an excellent example (http://www.dev-archive.com/forum/showpost.php?p=1625332&postcount=13) of a problem you might run into:
#include <iostream>
class L {
public:
L() { std::cout << "Object created\n"; }
~L() { std::cout << "Object destroyed\n"; }
};
int main()
{
L l;
std::cout << "Hello World!\n";
std::cin.get();
}
This isn't nearly as contrived as you may think, considering that most code that pauses at the end of main is part of a small tutorial or test project, which may very well have couts to keep track of memory allocations.
Cheers,
Zen
# 3 Re: Shortcut to my Release .exe
But why do I have to do that? Main calls a function called ghost which loops until the user exits. It shouldn't close while this loop is still going..
int main(int argc, char* args[])
{
bool exit_game = false;
User_Interface UI;
SDL_Event event_;
//Initialise user interface
if(UI.Initialise() == EXIT_PROGRAM) {
return 1;
}
// Add images, buttons etc.
if(initialise(UI) == EXIT_PROGRAM)
{
return 1;
}
//Update the screen
if(UI.Update_Screen() == EXIT_PROGRAM) {
return 1;
}
//While the user hasn't exit
while(!exit_game) {
//Update the screen
if(UI.Update_Screen() == EXIT_PROGRAM) {
return 1;
}
//While there's events to handle
while(SDL_PollEvent(&event_)) {
//If the user has Xed out
if(event_.type == SDL_QUIT) {
//Exit
exit_game = true;
break;
}
else if(event_.type == SDL_MOUSEBUTTONDOWN) {
UI.Remove_Image(INTRO_FN);
if(ghost(UI, event_) == EXIT_PROGRAM) {
//Player wanted to exit or there was an error
exit_game = true;
break;
}
}
}
}
//Exit SDL_ttf, SDL and User_Interface and Draw_Engine
UI.Clean_Up();
SDL_Quit();
return 0;
}
There is an intro screen which stays up until a user clicks a button, and then ghost is called, which runs until the user exits.
# 4 Re: Shortcut to my Release .exe
Did you debug the application and see what happens?
cilu at 2007-11-9 1:27:52 >

# 5 Re: Shortcut to my Release .exe
Try adding some debug output statements... do you even reach that inner loop?
# 6 Re: Shortcut to my Release .exe
Yes debugging works fine it does exactly what it should do. (loop and wait for mouse motion/keypress). It's only when I open the release .exe in C:\Documents and Settings\User\My Documents\Visual Studio 2005\Projects\HEX\Ghost\release that it closes quickly. The intro screen doesn't even come up. :o
# 7 Re: Shortcut to my Release .exe
If you have a good debugger (e.g. MSVC), you can also debug the release version. Otherwise you'll have to go back to the good old std::cerr << "Debug: I got here." << std::endl; method of debugging.
Afraid I'm not familiar enough with SDL to help you much more than that...
Cheers,
Zen
Edit: What happens if you launch it from MSVC, *without* debugging?
# 8 Re: Shortcut to my Release .exe
Yeah I debugged the release version (I have VS2005), and I don't know what you mean by cerr or launching it from msvc without debugging. :s
# 9 Re: Shortcut to my Release .exe
Hmm, interesting...
Have you tried running it from the windows command shell (rather than by double-clicking the .exe)? Not sure what else to try...
With debug statements I just meant printing some text to the console that shows the flow of code in your program without needing to launch it in the IDE. At least to figure out which of your various returns it uses to get out of main.
Cheers,
Zen
# 10 Re: Shortcut to my Release .exe
Hmm, interesting...
Have you tried running it from the windows command shell (rather than by double-clicking the .exe)? Not sure what else to try...
With debug statements I just meant printing some text to the console that shows the flow of code in your program without needing to launch it in the IDE. At least to figure out which of your various returns it uses to get out of main.
Cheers,
Zen
Yep I've tried running it from command.
I'll try that print idea it seems good. :thumb:
# 11 Re: Shortcut to my Release .exe
Ok. I tried debugging in release mode again and this time I got more results for some reason.
I pinpointed what was going wrong to the returns (in red) in this code:
RETURN_CODE initialise(User_Interface& UI)
{
if(!Is_Valid_File_Name(INTRO_FN) ||
!Is_Valid_File_Name(BG_FN) ||
!Is_Valid_File_Name(PLAY_ANIMATION_FN) ||
!Is_Valid_File_Name(STOP_ANIMATION_FN) ||
!Is_Valid_File_Name(LOAD_CHARSET_FN) ||
!Is_Valid_File_Name(EXIT_FN)
)
{
return EXIT_PROGRAM;
}
if(UI.Add_Image(Image(0, 0, INTRO_FN, IMAGE, INTRO.x, INTRO.y)) == EXIT_PROGRAM)
return EXIT_PROGRAM;
if(UI.Add_Image(Image(0, 0, BG_FN, BACKGROUND_IMAGE, BG.x, BG.y)) == EXIT_PROGRAM)
return EXIT_PROGRAM;
if(UI.Add_Button(Button(
AC_PLAY_ANIMATION, PLAY_ANIMATION_FN, "Play animation.", 0, BUTTON, PLAY_ANIMATION.x, PLAY_ANIMATION.y,
PLAY_ANIMATION_OFF, PLAY_ANIMATION_OVER, PLAY_ANIMATION_DOWN)) == EXIT_PROGRAM)
return EXIT_PROGRAM;
if(UI.Add_Button(Button(
AC_STOP_ANIMATION, STOP_ANIMATION_FN, "Stop animation.", 0, BUTTON, STOP_ANIMATION.x, STOP_ANIMATION.y,
STOP_ANIMATION_OFF, STOP_ANIMATION_OVER, STOP_ANIMATION_DOWN)) == EXIT_PROGRAM)
return EXIT_PROGRAM;
if(UI.Add_Button(Button(
AC_CLEAR_CHARSET, CLEAR_CHARSET_FN, "Clear the charset frame.", 0, BUTTON, CLEAR_CHARSET.x, CLEAR_CHARSET.y,
CLEAR_CHARSET_OFF, CLEAR_CHARSET_OVER, CLEAR_CHARSET_DOWN)) == EXIT_PROGRAM)
return EXIT_PROGRAM;
if(UI.Add_Button(Button(
AC_LOAD_CHARSET, LOAD_CHARSET_FN, "Load a charset.", 0, BUTTON, LOAD_CHARSET.x, LOAD_CHARSET.y,
LOAD_CHARSET_OFF, LOAD_CHARSET_OVER, LOAD_CHARSET_DOWN)) == EXIT_PROGRAM)
return EXIT_PROGRAM;
if(UI.Add_Button(Button(
AC_EXIT, EXIT_FN, "Exit Ghost.", 0, BUTTON, EXIT.x, EXIT.y,
EXIT_OFF, EXIT_OVER, EXIT_DOWN)) == EXIT_PROGRAM)
return EXIT_PROGRAM;
return SUCCESSFUL;
}
For any Add_... function to return SUCCESSFUL, it must go through DE.Load_Image() as shown below. While debugging (in release still), every Add_... function returns successful, but the debugger hits every return EXIT_PROGRAM line above (in red)... EVEN THOUGH it hits these lines, it doesn't return to main()! It keeps on going and hits the line in blue! Does anyone know WHY this is?
RETURN_CODE User_Interface::Add_Image(Image image)
{
if(!DE.Load_Image(image))
{
return EXIT_PROGRAM;
}
images.push_back(image);
return SUCCESSFUL;
}
Edit: If I add some junk stuff into the code (in green below), it skips that as well. I understand optimisations to a degree, but why would it hit the return EXIT_PROGRAM (and keep on going) and skip the b = true, and then go and do more and not just return to main? Ahhh! :confused: :thumbd:
bool b = false;
if(UI.Add_Image(Image(0, 0, INTRO_FN, IMAGE, INTRO.x, INTRO.y)) == EXIT_PROGRAM) {
return EXIT_PROGRAM;
b = true;
}
# 12 Re: Shortcut to my Release .exe
Ok. I tried debugging in release mode again and this time I got more results for some reason.
I pinpointed what was going wrong to the returns (in red) in this code:
RETURN_CODE initialise(User_Interface& UI)
{
if(!Is_Valid_File_Name(INTRO_FN) ||
!Is_Valid_File_Name(BG_FN) ||
!Is_Valid_File_Name(PLAY_ANIMATION_FN) ||
!Is_Valid_File_Name(STOP_ANIMATION_FN) ||
!Is_Valid_File_Name(LOAD_CHARSET_FN) ||
!Is_Valid_File_Name(EXIT_FN)
)
{
return EXIT_PROGRAM;
}
if(UI.Add_Image(Image(0, 0, INTRO_FN, IMAGE, INTRO.x, INTRO.y)) == EXIT_PROGRAM)
return EXIT_PROGRAM;
if(UI.Add_Image(Image(0, 0, BG_FN, BACKGROUND_IMAGE, BG.x, BG.y)) == EXIT_PROGRAM)
return EXIT_PROGRAM;
if(UI.Add_Button(Button(
AC_PLAY_ANIMATION, PLAY_ANIMATION_FN, "Play animation.", 0, BUTTON, PLAY_ANIMATION.x, PLAY_ANIMATION.y,
PLAY_ANIMATION_OFF, PLAY_ANIMATION_OVER, PLAY_ANIMATION_DOWN)) == EXIT_PROGRAM)
return EXIT_PROGRAM;
if(UI.Add_Button(Button(
AC_STOP_ANIMATION, STOP_ANIMATION_FN, "Stop animation.", 0, BUTTON, STOP_ANIMATION.x, STOP_ANIMATION.y,
STOP_ANIMATION_OFF, STOP_ANIMATION_OVER, STOP_ANIMATION_DOWN)) == EXIT_PROGRAM)
return EXIT_PROGRAM;
if(UI.Add_Button(Button(
AC_CLEAR_CHARSET, CLEAR_CHARSET_FN, "Clear the charset frame.", 0, BUTTON, CLEAR_CHARSET.x, CLEAR_CHARSET.y,
CLEAR_CHARSET_OFF, CLEAR_CHARSET_OVER, CLEAR_CHARSET_DOWN)) == EXIT_PROGRAM)
return EXIT_PROGRAM;
if(UI.Add_Button(Button(
AC_LOAD_CHARSET, LOAD_CHARSET_FN, "Load a charset.", 0, BUTTON, LOAD_CHARSET.x, LOAD_CHARSET.y,
LOAD_CHARSET_OFF, LOAD_CHARSET_OVER, LOAD_CHARSET_DOWN)) == EXIT_PROGRAM)
return EXIT_PROGRAM;
if(UI.Add_Button(Button(
AC_EXIT, EXIT_FN, "Exit Ghost.", 0, BUTTON, EXIT.x, EXIT.y,
EXIT_OFF, EXIT_OVER, EXIT_DOWN)) == EXIT_PROGRAM)
return EXIT_PROGRAM;
return SUCCESSFUL;
}
For any Add_... function to return SUCCESSFUL, it must go through DE.Load_Image() as shown below. While debugging (in release still), every Add_... function returns successful, but the debugger hits every return EXIT_PROGRAM line above (in red)... EVEN THOUGH it hits these lines, it doesn't return to main()! It keeps on going and hits the line in blue! Does anyone know WHY this is?
RETURN_CODE User_Interface::Add_Image(Image image)
{
if(!DE.Load_Image(image))
{
return EXIT_PROGRAM;
}
images.push_back(image);
return SUCCESSFUL;
}
Edit: If I add some junk stuff into the code (in green below), it skips that as well. I understand optimisations to a degree, but why would it hit the return EXIT_PROGRAM (and keep on going) and skip the b = true, and then go and do more and not just return to main? Ahhh! :confused: :thumbd:
bool b = false;
if(UI.Add_Image(Image(0, 0, INTRO_FN, IMAGE, INTRO.x, INTRO.y)) == EXIT_PROGRAM) {
return EXIT_PROGRAM;
b = true;
}
This could just be some odd behavior on the part of the debugger. In that last bit of code, have you tried switching the lines "b = true" and "return EXIT_PROGRAM"? First of all, an optimizer is definitely going to discard any code below and in the same block as a return statement. Switching the lines would also reveal whether or not it's some weird issue with the line numbers of the breakpoints.
I'd say to make sure that all of the breakpoints are being hit with the same call, but the fact that every one is being hit is too suspicious for that to be the likely cause.
# 13 Re: Shortcut to my Release .exe
I switched it around and the b = true; still gets skipped.
I put breakpoints on all of the function calls in initialise() except for the Is_Valid_File_Name() calls since they work normally. When I hit debug, the red lines below were the only breakpoints that stayed. For some reason, the last Add_... function doesn't have it's return EXIT_PROGRAM; line hit now... What the hell??
RETURN_CODE initialise(User_Interface& UI)
{
if(!Is_Valid_File_Name(INTRO_FN) ||
!Is_Valid_File_Name(BG_FN) ||
!Is_Valid_File_Name(PLAY_ANIMATION_FN) ||
!Is_Valid_File_Name(STOP_ANIMATION_FN) ||
!Is_Valid_File_Name(LOAD_CHARSET_FN) ||
!Is_Valid_File_Name(EXIT_FN)
)
{
return EXIT_PROGRAM;
}
if(UI.Add_Image(Image(0, 0, INTRO_FN, IMAGE, INTRO.x, INTRO.y)) == EXIT_PROGRAM)
return EXIT_PROGRAM;
if(UI.Add_Image(Image(0, 0, BG_FN, BACKGROUND_IMAGE, BG.x, BG.y)) == EXIT_PROGRAM)
return EXIT_PROGRAM;
if(UI.Add_Button(Button(
AC_PLAY_ANIMATION, PLAY_ANIMATION_FN, "Play animation.", 0, BUTTON, PLAY_ANIMATION.x, PLAY_ANIMATION.y,
PLAY_ANIMATION_OFF, PLAY_ANIMATION_OVER, PLAY_ANIMATION_DOWN)) == EXIT_PROGRAM)
return EXIT_PROGRAM;
if(UI.Add_Button(Button(
AC_STOP_ANIMATION, STOP_ANIMATION_FN, "Stop animation.", 0, BUTTON, STOP_ANIMATION.x, STOP_ANIMATION.y,
STOP_ANIMATION_OFF, STOP_ANIMATION_OVER, STOP_ANIMATION_DOWN)) == EXIT_PROGRAM)
return EXIT_PROGRAM;
if(UI.Add_Button(Button(
AC_CLEAR_CHARSET, CLEAR_CHARSET_FN, "Clear the charset frame.", 0, BUTTON, CLEAR_CHARSET.x, CLEAR_CHARSET.y,
CLEAR_CHARSET_OFF, CLEAR_CHARSET_OVER, CLEAR_CHARSET_DOWN)) == EXIT_PROGRAM)
return EXIT_PROGRAM;
if(UI.Add_Button(Button(
AC_LOAD_CHARSET, LOAD_CHARSET_FN, "Load a charset.", 0, BUTTON, LOAD_CHARSET.x, LOAD_CHARSET.y,
LOAD_CHARSET_OFF, LOAD_CHARSET_OVER, LOAD_CHARSET_DOWN)) == EXIT_PROGRAM)
return EXIT_PROGRAM;
if(UI.Add_Button(Button(
AC_EXIT, EXIT_FN, "Exit Ghost.", 0, BUTTON, EXIT.x, EXIT.y,
EXIT_OFF, EXIT_OVER, EXIT_DOWN)) == EXIT_PROGRAM)
return EXIT_PROGRAM;
return SUCCESSFUL;
}
Cheers for all your help so far!
