Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Nested function
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
== Implementation == {{see also|Man or boy test}} Implementation of nested functions can be more involved than it may appear, as a reference to a nested function that references non-local variables creates a [[Closure (computer science)|closure]]. For this reason nested functions are not supported in some languages such as C, C++ or Java as this makes compilers more difficult to implement.<ref name=cfaq /><ref>[https://stackoverflow.com/a/1348456/2025416 answer] by Dave Vandervies, Aug 28 '09 at 17:45, to "[https://stackoverflow.com/questions/1348095/why-are-nested-functions-not-supported-by-the-c-standard Why are nested functions not supported by the C standard?]"</ref> However, some compilers do support them, as a compiler specific extension. A well known example of this is the [[GNU C]] implementation of C which shares code with compilers for languages such as Pascal, Ada and Modula. === Access of non-local objects === There are several ways to implement nested procedures in a lexically scoped language, but the classic way is as follows: :Any [[non-local object]], X, is reached via access-links in the [[call stack|activation frames]] on the machine stack. The caller, C, assists the called procedure, P, by pushing a ''direct'' link to the ''latest'' activation of P's immediate lexical encapsulation, (P), prior to the call itself. P may then quickly find the right activation for a certain X by following a ''fixed number'' (P.depth β X.depth) of links (normally a small number). :The caller creates this direct link by (itself) following C.depth β P.depth + 1 older links, leading up to the latest activation of (P), and then ''temporarily'' bridging over these with a direct link to that activation; the link later disappears together with P, whereby the older links beneath it may come into use again. :Note that P is visible for, and may therefore be called by, C if (P) = C / (C) / ((C)) / etc. This original method is faster than it may seem, but it is nevertheless often optimized in practical modern compilers (using [[Call stack#Display|''displays'']] or similar techniques). Another way to implement nested functions that is used by some compilers is to convert ("lift") nested functions into non-nested functions (where extra, hidden, parameters replace the access links) using a process known as [[lambda lifting]] during an intermediate stage in the compilation. === Functions as values === In order for local functions with [[lexically scoped]] [[non-local variable|nonlocals]] to be passed as results, the language runtime code must also implicitly pass the environment (data) that the function sees inside its encapsulating function, so that it is reachable also when the current activation of the enclosing function no longer exists.<ref>Such a combination of function code and its environment is sometimes called a [[Closure (computer programming)|closure]].</ref> This means that the environment must be stored in another memory area than (the subsequently reclaimed parts of) a chronologically based execution stack, which, in turn, implies some sort of freely [[dynamic memory allocation]]. Many older Algol based languages (or dialects thereof) does therefore not allow local functions that access nonlocals to be passed as return values, or do they not allow functions as return values at all, although passing of such functions as arguments may still be possible. === No-execute stacks === [[GNU Compiler Collection|GCC]]'s implementation of nested functions causes a loss of [[NX bit|no-execute]] [[Call stack|stacks]] (NX stacks). This implementation calls nested functions through a [[jump instruction]] placed on the machine stack at runtime. This requires the stack to be executable. No-execute stacks and nested functions are therefore mutually exclusive in GCC. If a nested function is used in the development of a program, then the NX stack is silently lost, unless GCC is called with the <code>‑Wtrampoline</code> option to alert of the condition. Software engineered using [[Software Development Security|Secure Development Lifecycle]] often do not allow the use of nested functions in this particular compiler due to the loss of NX stacks.<ref>{{cite web | url = http://www.owasp.org/index.php/C-Based_Toolchain_Hardening#GCC.2FBinutils | title = C-Based Toolchain Hardening | last = Walton | first = Jeffrey | publisher = The Open Web Application Security Project (OWASP) | access-date = 28 February 2017 }}</ref>
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)