Thread: Lower Functions

  1. #1
    Registered User
    Join Date
    Nov 2007
    Location
    Free Country, USA
    Posts
    105

    Lower Functions

    Another question: Is it possible to call a function that has already executed and is below a function that is calling it? I get an error when I try to do this:
    Code:
    int somefunction()
    {
           main();
    }
    
    int main()
    {
           somefunction();
    }
    I'm using Dev C++ compiler.

    I need this for the game I mentoined in my last post.
    Last edited by DarkAlex; 11-28-2007 at 10:54 PM.

  2. #2
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    You might be able to do that in C, but not in C++. Instead you'd use some form of loop:
    Code:
    int main()
    {
    	for (;;)
    	{
    		somefunction();
    	}
    }
    Or:
    Code:
    int main()
    {
    	while (true)
    	{
    		somefunction();
    	}
    }
    Or:
    Code:
    int main()
    {
    	do {
    	{
    		somefunction();
    	} while (true);
    }
    You can also add some condition to the loop, which as long as the condition is true, the loop will continue to execute.

  3. #3
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    In general you can. In fact it is quite common to have functions call one another in a recursive descent parser.

    I'm pretty sure you're not allowed to call 'main' recursively though, which could be the problem you're running into.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  4. #4
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Quote Originally Posted by iMalc View Post
    In general you can. In fact it is quite common to have functions call one another in a recursive descent parser.

    I'm pretty sure you're not allowed to call 'main' recursively though, which could be the problem you're running into.
    That being the case, maybe instead of calling main(), do this instead:
    Code:
    int somefunction();
    int someotherfunction();
    
    int main()
    {
           somefunction();
    }
    
    int somefunction()
    {
           someotherfunction();
    }
    
    int someotherfunction()
    {
           somefunction();
    }

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    The compiler will only know functions that are above your current function, unless you add declarations that say "these functions do exist," as swoopy shows you. It's common and good practice to add declarations for all your functions.

  6. #6
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    That's actually something I've wondered for a while... Is there any easy way (portable or not) to see the call stack, kind of like the BT command in gdb? Java can do it, which I find very nice in debugging, but it would be nice if I could print the call stack in C or C++ along with an error message.

  7. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Not portably. You have to walk the stack yourself, often relying on accompanying debug information to do so. And due to inlining, that stack may not be what you'd expect from the code.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, as CornedBee says, it's unportable and depends on debug info.

    You can quite easily write a function that dumps the stack in hex, and, if you can get a machine-readable form of the symbol table, can give you the function names from this.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Yeah, that's pretty much what I figured.

  10. #10
    Registered User
    Join Date
    Nov 2007
    Location
    Free Country, USA
    Posts
    105
    Thank you, swoopy. That really helps. The game invoves rooms that might need to be revisited.

  11. #11
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by matsp View Post
    You can quite easily write a function that dumps the stack in hex, and, if you can get a machine-readable form of the symbol table, can give you the function names from this.
    The following should work on Intel-type architectures where the calling convention is "Push Args, Push Return, Push Base Pointer." The recur() and recur2() functions are just for demonstration. main() is proxied to trace(), in order to avoid any weirdness caused by main() not being a "normal" function. Calling backtrace(0) at any point will dump a raw trace, which you can fairly easily match up with function names by referring to a link map:

    Code:
    #include <stdio.h>
    
    void recur(int n);
    void recur2(int n);
    
    unsigned int *base_top;
    
    void backtrace(unsigned int dummy)
    {
       unsigned int *base = &dummy - 2;
       unsigned int *ret = base + 1;
    
       printf("0x%08x\n", *ret);
       while(*base != (unsigned int)base_top)
       {
          base = (unsigned int *)*base;
          ret = base + 1;
          printf("0x%08x\n", *ret);
       }
    }
    
    void recur(int n)
    {
       if(!n)
       {
          backtrace(0);
       }
       else
       {
          recur2(n);
       }
    }
    
    void recur2(int n)
    {
       recur(n - 1);
    }
    
    int trace(int argc, char **argv)
    {
       base_top = (unsigned int *)&argc - 2;
       recur(10);
    }
    
    int main(int argc, char **argv)
    {
       return trace(argc, argv);
    }
    Downside: Not portable, and liable to crash if the stack is not in pristine condition. Compiler optimizations may obscure your trace or cause it to explode. I provide no warranty

  12. #12
    Registered User
    Join Date
    Nov 2007
    Location
    Free Country, USA
    Posts
    105
    Um, I was just using main() as an example, sorry for confusion.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Factory Functions HOWTO
    By GuardianDevil in forum Windows Programming
    Replies: 1
    Last Post: 05-01-2004, 01:41 PM
  2. Shell functions on Win XP
    By geek@02 in forum Windows Programming
    Replies: 6
    Last Post: 04-19-2004, 05:39 AM
  3. Inline functions and inheritance
    By hpy_gilmore8 in forum C++ Programming
    Replies: 3
    Last Post: 01-14-2004, 06:46 PM
  4. Embedded functions...
    By dead_cell in forum C++ Programming
    Replies: 3
    Last Post: 06-30-2002, 08:18 PM
  5. API "Clean Up" Functions & delete Pointers :: Winsock
    By kuphryn in forum Windows Programming
    Replies: 2
    Last Post: 05-10-2002, 06:53 PM