Is There Any Use for Local Function Declarations

Is there any use for local function declarations?

I've wanted local function declarations in C when I wanted to pass them as arguments to some other function. I do this all the time in other languages. The reason is to encapsulate the implementation of data structures.

E.g. I define some data structure, e.g. a tree or a graph, and I don't want to expose the details of its internal implementation, e.g. because I may want to change or vary it. So I expose accessor and mutator functions for its elements, and a traversal function to iterate over the elements. The traversal function has as its argument a function that operates on an element; the traversal function's task is to execute the argument function on each element and possibly aggregate the results in some way. Now when I call the traversal function, the argument function is usually some specialized operation that depends on local state and therefore should be defined as a local function. Having to push the function, with the variables that contain the local state, outside to be global, or into an inner class created specifically to hold them, is butt ugly. But this is a problem I have with C and Java, not with C++.

What is C local function declaration mechanism?

Both ISO C and C++ permit local function declarations. In each case the scope of the function declaration ends at the end of the local scope. However, the function declaration and its definition have external linkage so they still need to be acceptable to the linker.

In your sample:

int main(void) {
int f(void);
f();
}
void f(void);
void f(void) { }

This code compiles without error, as either C or C++. In C is should link (usually), but in C++ it will not (because of "typesafe linkage"). There will be an unresolved external for int f(void);.

[If this does not answer your question because of difficulties with your English, please clarify and I'll edit the answer.]


The C standard contains the following. n1570/S6.7.1/7:

The declaration of an identifier for a function that has block scope shall have no explicit
storage-class specifier other than extern.

Clearly local function declarations are explicitly permitted.


n1570 S6.2.2/5 on external linkage:

If the declaration of an identifier for a function has no storage-class specifier, its linkage
is determined exactly as if it were declared with the storage-class specifier extern. If
the declaration of an identifier for an object has file scope and no storage-class specifier,
its linkage is external.

So local function declarations have external linkage. This is obvious: if they had internal or no linkage, they could not link to anything.

Must Kotlin Local Functions be Declared Before Use

It's not a bug, it is the designed behavior.

When you use a symbol (variable, type or function name) in an expression, the symbol is resolved against some scope. If we simplify the scheme, the scope is formed by the package, the imports, the outer declarations (e.g. other members of the type) and, if the expression is placed inside a function, the scope also includes the local declarations that precede the expression.

So, you can't use a local function until it's declared just like you cannot use a local variable that is not declared up to that point: it's just out of scope.

Why are local function definitions illegal in C++?

Oddly enough, local function 'Declarations' are allowed, but definitions are not. And the rule on local function definitions not being allowed can be easily bypassed by writing a class encapsulator. So, could I have some clarification? Why are local class definitions classified as 'illegal' in C++?

Illegal because they don't make much sense, whether it may be defining a function inside a function or a class inside a function like main().

But then you can always use workarounds, such as:

  • For functions you can always use a lambda, which acts as an anonymous temporary function, can be called inside main plus be used within function parameters as well.

It can be invoked whenever necessary and subsequently discarded like a throw-away function, but it does the job - whatever you would expect from a function.

Example:

int main() 
{
// Define within the scope of main()
auto temp = [](int x)
{ std::cout<< x;
}
temp(10); // call like a function
}

  • For classes, use static functions, (being local to the translation unit) with public access specifiers (as you did in your question).

Example:

int main()
{
class temp
{ public:
static void a()
{ std::cout<< 10;
}
};
temp::a();
}

Output for both cases: 10

Provided there are alternatives approaches like the ones above to define a function/class/struct inside main(), there isn't really much of a point to make them legal. ¯\_(ツ)_/¯

Define local function in JavaScript: use var or not?

Actually there are 3 ways to declare a function:

  1. Function declaration: A Function Declaration defines a named function variable without requiring variable assignment. Function Declarations occur as standalone constructs and cannot be nested within non-function blocks. ex: function innerFunction1 () { };

  2. Function expression:: A Function Expression defines a function as a part of a larger expression syntax (typically a variable assignment). Functions defined via Function Expressions can be named or anonymous:

    a. Using an anonymous function - var innerFunction1 = function() { };

    b. Using a named function - var innerFunction1 = function myInnerFunction () { };

  3. Function constructor: A Function Constructor defines a function dynamically using the Function( ) constructor. Note that the function body is passed to the function as a string argument. var innerFunction1 = new Function (arg1, arg2, ... argN, functionBody)

The third method is not recommended because passing the function body as a string may prevent some JS engine optimizations, and it is prone to errors.

The differences between function declaration and function expression are subtle and you should choose whichever method suits your requirements best.

I use function expression where I need

  1. a singleton function, or
  2. to determine which function to use programmatically (using a named function expression).

Some differences between a function declaration and a function expression are:

  1. Function expressions allow you to assign different functions to the same variable at different points.
  2. A function defined by a function declaration can be used before the function declaration itself (or basically anywhere in the current scope), whereas a function defined by a function expression can only be used after the point it is defined.

Click here to read the detailed comparison of Function Declaration vs Function Expression vs Function Constructor @MDN

Note: A function declaration can be easily turned into a function expression by assigning it to a var.

function foo() {}
alert(foo); // alerted string contains function name "foo"
var bar = foo;
alert(bar); // alerted string still contains function name "foo"

More Reading:

  • http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html
  • http://javascriptweblog.wordpress.com/2010/07/06/function-declarations-vs-function-expressions/
  • http://msdn.microsoft.com/en-us/library/ie/x844tc74%28v=vs.94%29.aspx
  • http://es5.github.io/#x15.3
  • var functionName = function() {} vs function functionName() {}

C/C++ need for local functions prototypes?

There are cases when you need to declare the function prototype beforehand, i.e. the compiler needs to know a functions prototype before you are able to use that function.

Consider these functions that do nothing particularly useful:

int foo(int x)
{
if(x < 1) return x;
else return x + bar(x-1);
}

int bar(int x)
{
if(x < 3) return x;
return x * foo(x-1);
}

If you try to compile this, the compiler gets mad at you:

error: 'bar' was not declared in this scope

You need to put the missing prototypes in front of the function using it:

int bar(int);
// as above unchanged

This is the only case where the compiler requires you to put a function prototype before your functions. In all other cases it is perfectly legal to put prototypes anywhere as often as you'd like, so this is also legal:

int foo(int);
int bar(int);
int foo(int);
int bar(int);

Though obviously redundant (please don't do that). Some people consider it good style to put a function prototype of every function within a file at the top of the file, because

  1. you don't have to care about cases in which the compiler requires you to do it anymore, and some people apparently cannot interpret the error message by the compiler (which I think is very concise), and
  2. you see on one view what functions are provided by the file and how they are called.

But this is exactly that, a style discussion. I like to keep my code as short as possible, so I would only use the prototypes that are required by the compiler, but that's purely a matter of taste and convention. When in Rome, do as the Romans or something like that.

How does local function myFunc() works in lua?

In Lua, when you write:

local function myFunc()
--...
end

It is essentially the same thing as:

local myFunc = function()
--...
end

In the same manner, the following:

function myFunc()
--...
end

Is the same as:

myFunc = function()
--...
end

It's simply a shortcut for variable declaration. That's because in Lua, functions are first class objects, there is no special place where declared functions are stored, they are held in variables the same as any other data type.

Caveat

It's worth noting that there is a very small difference in behavior when using local function myFunc() instead of local myFunc = function().

When you declare the function using the former syntax, code inside the function has access to the variable myFunc, so the function can refer to itself. With the latter syntax, accessing myFunc inside of myFunc will return nil - it's not in scope.

So that means the following code:

local function myFunc()
--...
end

Is actually more accurately represented as:

local myFunc
myFunc = function()
--..
end

This is a small difference, but may be worth keeping in mind e.g. if you need to write a recursive function.

Is there a use for function declarations inside functions?

This is really a C question, because this behaviour was inherited directly from C (although it gets much more press in C++ because of the most vexing parse).

I suspect the answer (in the context of C, at least) is that this allows you to scope the existence of your function declarations to precisely where they're needed. Maybe that was useful in the early days of C. I doubt anyone does that any more, but for the sake of backward compatibility it can't be removed from the language.

Does C++11 have any support for local functions?

There are no local functions, but they are not so useful without the closure, that is, access to the local variables. In any case you can emulate a local function with a lambda easy enough.

Instead of:

void foo(int x)
{
struct S
{
//...
};
int Twice(int n, S *s) //Not allowed
{
return 2*n;
}

S s;
int x = Twice(3, &s);
//...
}

Do:

void foo()
{
struct S
{
//...
};
auto Twice = [](int x, S *s) -> int //Cool!
{
return 2*x;
}; //Twice is actually a variable, so don't forget the ;

S s;
int x = Twice(3, &s);
//...
}

If the capture set is empty, ([]) it can even be converted to an ordinary pointer-to-function, just like a real one!

And AFAIK, lambdas can use local types without trouble. But, of course, public static member functions in that struct should work also fine.

And as an additional note, indirectly related to your question, what it is allowed in C++11 is to instantiate a template using a local type (that was forbidden in C++98):

void foo()
{
struct S {};
std::vector<S> vs; //error in C++98, ok in C++11
}

Why declare a local function static in C# 8.0

This answer from CodeCaster and this separate answer from György Kőszeg individually answer different parts of my question, so I'm bringing them both together to form the full picture for the accepted answer:

For Part 1) of my question, @CodeCaster Says:

Because it prevents you from shooting yourself in the foot. It forces the local function to be a pure function that does not modify the state of the caller.

in larger codebases maintained by multiple people and not properly covered by unit tests, this simple modifier prevents grief

So Answer 1 is: Static Local Functions ensure reliable caller method state.

For Part 2) of my question, @György Kőszeg Says:

Capturing variables has a small additional cost as it will generate an internally used type where your captured variables are public fields

And he goes on to give an example of the produced compiler code via reflector.

So Answer 2 is: Static Local Functions prevent variable capturing. Variable capturing comes at a small cost. So there is a small performance boost by declaring the local function static



Related Topics



Leave a reply



Submit