Skip to main content
gamedev.net
🔒 Locked

Function in function

Started by Lode Jan 18, 2005 at 7:53 AM 14 replies 1k views
Original Post
Lode
Lode
Wouldn't it be handy if you could do something like this?

int whisky(int a, int b)
{
    int c = a * b;

    int tango(int x);
    int foxtrot(int x);

    c = tango(a + c) * foxtrot(b);

    return c;

    int tango(int x)
    {
        return x * a;
    }

    int foxtrot(int x)
    {
        return tango(a + b + c + x);
    }
}
A function inside a function allows you to do things with variables in your big function, without having to make them global! Is there a language that can do this?
Gorax
Gorax
You could always use c/c++, and more specifically, the define macro.

int whisky(int a, int b){  int c = a * b;    #define tango(x)     (x * a)    #define foxtrot(x)     tango(a + b + c + x)    c = tango(a + c) * foxtrot(b);    #undef tango  #undef foxtrot    return c;}
Erzengeldeslichtes
Erzengeldeslichtes
Do this in C++:
int whisky(int a, int b){    int c = a * b;class InnerFunc{    int &a, &b, &cpublic:    InnerFunc(int& a, int& b, int& c) : a(a), b(b), c(b) {}    int tango(int x)    {        return x * a;    }    int foxtrot(int x)    {        return tango(a + b + c + x);    }} InFunc(a, b, c);    c = InFunc.tango(a + c) * InFunc.foxtrot(b);    return c;}


You are allowed to define a class or structure within a function, so you can "cheat" the fact that you can't define a function within a function using a class that you define in your function. You'll still have to pass in the referances to the variables, it won't have access to the parent function's variables otherwise. Using Gorax's method you don't have to pass in the variables, but it is extremely unsafe. (at least put parenthesis around x! (that is: "#define tango(x) ((x)*a)" ))

[Edited by - Erzengeldeslichtes on January 18, 2005 8:04:43 AM]
----Erzengel des Lichtes光の大天使Archangel of LightEverything has a use. You must know that use, and when to properly use the effects.♀≈♂?
Emmanuel Deloget
Emmanuel Deloget
Quote:
Original post by Erzengeldeslichtes
Do this in C++:
*** Source Snippet Removed ***

You are allowed to define a class or structure within a function, so you can "cheat" the fact that you can't define a function within a function using a class that you define in your function. You'll still have to pass in the referances to the variables, it won't have access to the parent function's variables otherwise.


If you only need one function, then (using this inner class idea) you should use:
void func(type1 param1, type2 param2){   struct innerfunc   {     void operator()(type1 param1, type2 param2)     {       // do something     }   } my_innerfunc;   my_innerfunc(param1, param2); // really looks like an "internal" function call}


HTH,
Erzengeldeslichtes
Erzengeldeslichtes
Quote:
Original post by Emmanuel Deloget
Quote:
Original post by Erzengeldeslichtes
Do this in C++:
*** Source Snippet Removed ***

You are allowed to define a class or structure within a function, so you can "cheat" the fact that you can't define a function within a function using a class that you define in your function. You'll still have to pass in the referances to the variables, it won't have access to the parent function's variables otherwise.


If you only need one function, then (using this inner class idea) you should use:
void func(type1 param1, type2 param2){   struct innerfunc   {     void operator()(type1 param1, type2 param2)     {       // do something     }   } my_innerfunc;   my_innerfunc(param1, param2); // really looks like an "internal" function call}


HTH,

Ooh, good idea Emmanuel.
The big problem with this method is that you can't access data or functions in the "parent" function.

[Edited by - Erzengeldeslichtes on January 18, 2005 8:28:36 AM]
----Erzengel des Lichtes光の大天使Archangel of LightEverything has a use. You must know that use, and when to properly use the effects.♀≈♂?
Decibit
Decibit
Pascal allows you to use such functions and treats variables exactly the way you've described here. They are called 'nested' functions.

Nested functions are quite common. They can be easily realized on machine level. x86 assemly language even has two special instructions: ENTER and LEAVE that support this conception in hardware.

It's a matter of language design that C/C++ doesn't have nested functions. They provide no computational benefit and were not included.
Forfaox
Forfaox
Quote:
Original post by Lode
Is there a language that can do this?


Python and any Pascal variant seem to support this natively. There may be more languages, but I can't think of them right now [smile]
Fruny
Fruny
Quote:
Original post by Decibit
It's a matter of language design that C/C++ doesn't have nested functions. They provide no computational benefit and were not included.


Nested functions are legal in C, but illegal in C++.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Decibit
Decibit
Quote:
Original post by Fruny
Nested functions are legal in C, but illegal in C++.


Maybe. But MSVC++ NET 2003 doesn't compile them even when specifically told to compile files as C code sources. (/TC option).

What C do you mean: ANCI C or K&R C ?
Emmanuel Deloget
Emmanuel Deloget
Quote:
Original post by Erzengeldeslichtes
Ooh, good idea Emmanuel.
The big problem with this method is that you can't access data or functions in the "parent" function.


Then, as you did, I may provide a constructor :)

@The Great eye (aka Fruny): Are you sure? AFAIR this is legal in pascal, but C didn't provide any way to write nested functions. And since C++ is backward compatible with C, I would expect such a feature to be available in C++ if it is available in the C spec.

Regards,
Fruny
Fruny
Quote:
Original post by Anonymous Poster
That's a nonstandard GCC extension.


If so then thanks for the correction.

* contemplates suicide to safe face *
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Kylotan
Kylotan
Quote:
Original post by Lode
A function inside a function allows you to do things with variables in your big function, without having to make them global!

Is there a language that can do this?


As already mentioned, Pascal and Python allow it, as does Lua, &#106avascript, and Actionscript I think.<br><br>In C++ you can move a function into an unnamed namespace and that gives it file scope as opposed to global scope. This is not quite as good, but it reduces the chance of naming collisions if that's an issue.
Erzengeldeslichtes
Erzengeldeslichtes
Quote:
Original post by Emmanuel Deloget
Quote:
Original post by Erzengeldeslichtes
Ooh, good idea Emmanuel.
The big problem with this method is that you can't access data or functions in the "parent" function.


Then, as you did, I may provide a constructor :)

That's the way around the problem, but it's still a problem with both yours and mine--if I add data or "functions" to the "parent" function, I have to do a lot of modification to the object (constructor, member data) before I can make a modificaton to operator() or whatever other function I used. It's doable, just not as nice as if it were built in to the language that way.
----Erzengel des Lichtes光の大天使Archangel of LightEverything has a use. You must know that use, and when to properly use the effects.♀≈♂?
Sharlin
Sharlin
Quote:
Original post by Erzengeldeslichtes
Ooh, good idea Emmanuel.
The big problem with this method is that you can't access data or functions in the "parent" function.


There have been some proposals for C++0x to allow nested functions and even access to names in the parent's scope, but especially the latter feature brings some problems with it (and the former wouldn't be so useful without the latter...).

Full-blown closures would be nice, but they would practically require adding garbage-collection to the language (consider what happens when a pointer to a function accessing its parent's automatic variables is returned - the context would need to be retained or Bad Things happen next time someone calls the function).

Even a "watered-down" version would still be quite useful, though; one solution would be simply to declare the above example and its kind undefined behaviour, just like it now is undefined to return pointers/references to stack variables. Returning functions that only touch the parent's static variables would be perfectly OK; similarly nested functions could access the parent's auto variables provided that the parent doesn't return a pointer to such a function.

All this would certainly not be trivial to add to the standard, and would require some careful study. That said, at least I would very much like to see such functionality someday.

Topic Locked

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

Sign in to reply to this topic.