Thread: Changing default stack size with MinGW/GCC?

  1. #1
    Registered User
    Join Date
    Jun 2008
    Posts
    161

    Changing default stack size with MinGW/GCC?

    How can I get MinGW/GCC to compile my program with a bigger stack? I've been googling and nothing I could find actually worked. Running Windows 7 here.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Why do you need to do this? Maybe there is a better alternative.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Quote Originally Posted by Viper187 View Post
    I've been googling and nothing I could find actually worked. Running Windows 7 here.
    So you have already read Increase Stack Size on Windows (GCC) - Stack Overflow?

    Bye, Andreas

  4. #4
    Registered User
    Join Date
    Jun 2008
    Posts
    161
    Gah. It was Wl (L). I thought it was WI.

  5. #5
    Registered User
    Join Date
    Jun 2008
    Posts
    161
    Quote Originally Posted by laserlight View Post
    Why do you need to do this? Maybe there is a better alternative.
    Why do I need to screw around using malloc (and free) on an array of structs that's ALWAYS the same size just because it's a little big? With everyone running systems with gigabytes of RAM, why is the stack still defaulted to like 8MB? That's what I want to know. Why add extra coding just to save on a little memory? My thinking has always been that malloc should only be necessary for handling things of dynamic size. Like allocating an array to load some random file that could be any size.
    Last edited by Viper187; 03-21-2013 at 08:29 AM.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Because whatever <insert large number here> you think you've figured out, it's almost certain that at some future point in time it won't be big enough and you're back to editing the code (and fixing things).

    If you're just worried about say
    Code:
    int main ( ) {
        int array[1000000];
    }
    Then the quick and simple fix is to just do
    Code:
    int main ( ) {
        static int array[1000000];
    }
    and hey presto, no more stack space issues.

    > My thinking has always been that malloc should only be necessary for handling things of dynamic size. Like allocating an array to load some random file that could be any size.
    So your approach is to allocate several MB of "just in case", where 99% of the time very little of it will actually be used (small files), and the only time it will fail is when you try and process a file which won't fit in your statically sized buffer. That truly is a waste of resources.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Viper187 View Post
    Why do I need to screw around using malloc (and free) on an array of structs that's ALWAYS the same size just because it's a little big? With everyone running systems with gigabytes of RAM, why is the stack still defaulted to like 8MB? That's what I want to know. Why add extra coding just to save on a little memory? My thinking has always been that malloc should only be necessary for handling things of dynamic size. Like allocating an array to load some random file that could be any size.
    Well, the fact that you think that doesn't make it so.

    The purpose of the stack is to hold function invocation frames -- function parameters, return addresses, and local variables. It doesn't magically turn into something else just because you wish it.

    Back to your problem, if this thing is really fixed size and doesn't change, you could declare it as "static" which will put it in static memory instead of on the stack.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  8. #8
    Registered User
    Join Date
    Jun 2008
    Posts
    161
    Quote Originally Posted by Salem View Post
    Because whatever <insert large number here> you think you've figured out, it's almost certain that at some future point in time it won't be big enough and you're back to editing the code (and fixing things).

    > My thinking has always been that malloc should only be necessary for handling things of dynamic size. Like allocating an array to load some random file that could be any size.
    So your approach is to allocate several MB of "just in case", where 99% of the time very little of it will actually be used (small files), and the only time it will fail is when you try and process a file which won't fit in your statically sized buffer. That truly is a waste of resources.
    Not really, in this case. When I declare this array I use a defined constant for the size so anything else I use that relies on what size that array is all changes with changing one number in a header.

    No, when I load a file, I open it and find out the size, THEN malloc an array to hold it. That's what I mean by only using malloc for dynamic stuff. Arrays that I KNOW I want one size and things are coded to utilize that should not need malloc.

    Quote Originally Posted by brewbuck View Post
    Well, the fact that you think that doesn't make it so.

    The purpose of the stack is to hold function invocation frames -- function parameters, return addresses, and local variables. It doesn't magically turn into something else just because you wish it.

    Back to your problem, if this thing is really fixed size and doesn't change, you could declare it as "static" which will put it in static memory instead of on the stack.
    I never looked into how static variables differed from regular, but that's looking like a good choice.

    Here's an example of what I'm working with.... This is from a program I wrote a few years ago, Called Renegade. It's probably around 20 source files total. I'm in the process of reworking it a lot. It's a large program divided into tabs with a dialog loaded and slapped on each tab. Hey, it worked. The purpose of the program is to make cheat codes (Gameshark, etc) for console games that can be run in an emulator, since many emulators have limited or non-existent built in cheat functions. The last release version with source is here. Like I said, it's a ton of source...

    Code:
    //rex.h
    #define MAX_PRESETS 20
    #define MAX_MAP_BLOCK_NAME 15
    #define MAX_MAP_BLOCKS 1000
    #define SEARCH_LABEL_MAX 100
    
    typedef struct _SYS_VARS {
    	u32 ProcPoint[MAX_MAP_BLOCKS];
    	u32 ProcAddr[MAX_MAP_BLOCKS];
    	s32 ProcOffset[MAX_MAP_BLOCKS];
    	u32 SysAddr[MAX_MAP_BLOCKS];
    	u32 AreaSize[MAX_MAP_BLOCKS];
    	int AreaCount;
    	char AreaName[MAX_MAP_BLOCKS][MAX_MAP_BLOCK_NAME];
    } SYS_VARS;
    
    //Hook vars
    typedef struct _HOOK_VARS {
        char Name[1024];
        char HookType;
        char ProgramPath[MAX_PATH];
        char ProcName[MAX_PATH];
        int Endian;
        u32 SystemId;
        PROCESS_INFORMATION HookedProcess;
        SYS_VARS Sys;
    } HOOK_VARS;
    Code:
    //main.c
    SYS_VARS SysVars[NUM_SYSTEMS];
    extern HOOK_VARS Presets[MAX_PRESETS];
    
    BOOL CALLBACK MainProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
    {
    /......./
    case WM_INITDIALOG:
    {
    InitSysVars();
    }
    Code:
    //tab_hook.c
    HOOK_VARS Presets[MAX_PRESETS];
    
    //there's a bunch of possible handling in here for the dialog involving editing this array. It's either initialized with default values OR read in from a config file.
    Code:
    //lib_rex.c
    int InitSysVars()
    {
    	memset(SysVars, 0, sizeof(SYS_VARS)*NUM_SYSTEMS);
    	/***N64***/
    	SysVars[SYSTEM_N64].AreaCount = 2;
    	strcpy(SysVars[SYSTEM_N64].AreaName[0], "Lo-Res RAM\0");
    	SysVars[SYSTEM_N64].SysAddr[0] = 0x80000000;
    	SysVars[SYSTEM_N64].AreaSize[0] = 0x400000;
    	strcpy(SysVars[SYSTEM_N64].AreaName[1], "Hi-Res RAM\0");
    	SysVars[SYSTEM_N64].SysAddr[1] = 0x80400000;
    	SysVars[SYSTEM_N64].AreaSize[1] = 0x400000;
    	/***NDS***/
    	SysVars[SYSTEM_NDS].AreaCount = 1;
    	strcpy(SysVars[SYSTEM_NDS].AreaName[0], "RAM\0");
    	SysVars[SYSTEM_NDS].SysAddr[0] = 0x02000000;
    	SysVars[SYSTEM_NDS].AreaSize[0] = 0x400000;
    	/***PS1***/
    	SysVars[SYSTEM_PS1].AreaCount = 1;
    	strcpy(SysVars[SYSTEM_PS1].AreaName[0], "RAM\0");
    	SysVars[SYSTEM_PS1].SysAddr[0] = 0x80000000;
    	SysVars[SYSTEM_PS1].AreaSize[0] = 0x200000;
    	//need to find scratchpad
    	/***PS2***/
    	SysVars[SYSTEM_PS2].AreaCount = 1;
    	strcpy(SysVars[SYSTEM_PS2].AreaName[0], "EE\0");
    	SysVars[SYSTEM_PS2].SysAddr[0] = 0x00100000;
    	SysVars[SYSTEM_PS2].AreaSize[0] = 0x1F00000;
    	/***GB..........*/
    	SysVars[SYSTEM_GBA].AreaCount = 2;
    	strcpy(SysVars[SYSTEM_GBA].AreaName[0], "WRAM\0");
    	SysVars[SYSTEM_GBA].SysAddr[0] = 0x02000000;
    	SysVars[SYSTEM_GBA].AreaSize[0] = 0x40000;
    	strcpy(SysVars[SYSTEM_GBA].AreaName[1], "IRAM\0");
    	SysVars[SYSTEM_GBA].SysAddr[1] = 0x03000000;
    	SysVars[SYSTEM_GBA].AreaSize[1] = 0x8000;
    	return 0;
    }
    Last edited by Viper187; 03-21-2013 at 02:30 PM.

  9. #9
    Registered User
    Join Date
    Jun 2008
    Posts
    161
    I guess declaring a static in a header doesn't make it global. You can't extern a static, can you?

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Viper187
    I guess declaring a static in a header doesn't make it global. You can't extern a static, can you?
    The normal purpose of declaring a static variable at file scope is to make it restricted to the particular translation unit, hence it would not make sense to also declare it extern since that means that you want it to be global across translation units. On the other hand, you don't have to declare it static at file scope for it to have static storage duration and hence be likely to be stored similiarly to variables declared static.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    Registered User
    Join Date
    Jun 2008
    Posts
    161
    Quote Originally Posted by laserlight View Post
    The normal purpose of declaring a static variable at file scope is to make it restricted to the particular translation unit, hence it would not make sense to also declare it extern since that means that you want it to be global across translation units. On the other hand, you don't have to declare it static at file scope for it to have static storage duration and hence be likely to be stored similiarly to variables declared static.
    Well, static was suggested because of the stack issue I had run into. Can I make a global static? "Global" meaning I want to access the same array/struct/whatever from anywhere in the program, NOT just one file or function.

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Have you tried defining it at file scope in a single source file, then declaring it extern in a header? The static keyword was suggested in the context of a local variable, and indeed declaring a local variable to be static would give it static storage duration. However, if it is already at file scope (as an intended global variable would be), then it also has static storage duration. Declaring it static in such a case just ensures that it is "private" to the translation unit.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  13. #13
    Registered User
    Join Date
    Jun 2008
    Posts
    161
    Quote Originally Posted by laserlight View Post
    Have you tried defining it at file scope in a single source file, then declaring it extern in a header? The static keyword was suggested in the context of a local variable, and indeed declaring a local variable to be static would give it static storage duration. However, if it is already at file scope (as an intended global variable would be), then it also has static storage duration. Declaring it static in such a case just ensures that it is "private" to the translation unit.
    That's what I've been doing, and I broke the stack with it. I've been restructuring things to use less memory since then, but it still annoys me.

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Viper187
    That's what I've been doing, and I broke the stack with it.
    That's weird since the global array shouldn't be on the stack, although I believe that this is technically implementation detail.

    I suggest that you post the smallest and simplest compilable program that demonstrates this problem (though of course we may have to modify the array size as needed if we want to try it). My guess is that somewhere, you have another array or something that is local.

    Also, what is the version of the MinGW port of gcc that you are using?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #15
    Registered User ledow's Avatar
    Join Date
    Dec 2011
    Posts
    435
    The other reason, of course, to not change stack size is that the stack size necessary is then another "hidden" piece of information, that's not in the code, that everyone who compiles it has to replicate. If you don't replicate it, the program will mysteriously crash and you'll have to debug. Whether that's your friend, your tutor, someone on the Internet or even yourself 10 years from now, that's going to cause problems for no good reason.

    If you don't play with stack sizes, pretty much any code you ever come across will compile without you needing to adjust it (stack sizes do increase slightly over time but not by much at all, so you'll always be "backward compatible" if you don't touch the defaults). The second you start playing with stack size, everyone who touches the code (who might not be on the same architecture, or even an architecture that CAN do that) has to know and play with the stack size too. Sure, you can hide it in Makefiles and document it, but it makes the code less portable before you even start.

    And some embedded devices? If they can't get the stack size you want (which isn't unlikely with some smaller devices), they won't run it at all, or will crash doing the same things that other architectures do just because they ran out of stack space. Trying to debug problem X on an embedded device that's hard to debug data out of may seem far-fetched but people do it all the time. Stack space isn't really there for you to play around with. There's a lot more going on in it than just a convenient location to throw variables just to save you a couple of characters typing. Even the biggest of projects don't play around with stack space unless there's an absolute vital need (and usually only those that use the stack in excruciatingly accurate detail, like an operating system or similar).

    You can say "these things don't affect me at the moment" but the fact is that the bad habit will propagate until it DOES affect you, and then you'll have to get used to doing things the "better" way anyway. Think how many beginners say "I don't have to worry about indentation / global variables / goto / variable naming / commenting / separating out function prototypes / etc." - and eventually, one by one, you realise that there's a reason people got into those habits that has nothing to do with tradition or just doing things the way they've always done, but because there are good reasons behind it that you may not discover at first.

    Honestly, in the time the forum post took you to write, and for the reply about the command line switch to come back, you could have changed that line to a static or a malloc (or even, God forbid, look up the command line parameters for gcc yourself!) and be done with it.

    - Compiler warnings are like "Bridge Out Ahead" warnings. DON'T just ignore them.
    - A compiler error is something SO stupid that the compiler genuinely can't carry on with its job. A compiler warning is the compiler saying "Well, that's bloody stupid but if you WANT to ignore me..." and carrying on.
    - The best debugging tool in the world is a bunch of printf()'s for everything important around the bits you think might be wrong.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Changing default font in Emacs
    By dra in forum A Brief History of Cprogramming.com
    Replies: 2
    Last Post: 02-26-2008, 02:53 AM
  2. default stack size on modern Linux?
    By cyberfish in forum C++ Programming
    Replies: 3
    Last Post: 02-03-2008, 06:36 PM
  3. .exe size with MinGW
    By Stabbsy in forum C++ Programming
    Replies: 3
    Last Post: 11-16-2006, 06:07 AM
  4. changing default code in dev c++?
    By 7stud in forum C++ Programming
    Replies: 1
    Last Post: 12-15-2005, 05:06 PM
  5. Changing default unit in BCB 5
    By Mario in forum C++ Programming
    Replies: 0
    Last Post: 05-26-2002, 09:22 AM