Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I define a function inside another function?

This is not a lambda function question, I know that I can assign a lambda to a variable.

What's the point of allowing us to declare, but not define a function inside code?

For example:

#include <iostream>  int main() {     // This is illegal     // int one(int bar) { return 13 + bar; }      // This is legal, but why would I want this?     int two(int bar);      // This gets the job done but man it's complicated     class three{         int m_iBar;     public:         three(int bar):m_iBar(13 + bar){}         operator int(){return m_iBar;}     };       std::cout << three(42) << '\n';     return 0; } 

So what I want to know is why would C++ allow two which seems useless, and three which seems far more complicated, but disallow one?

EDIT:

From the answers it seems that there in-code declaration may be able to prevent namespace pollution, what I was hoping to hear though is why the ability to declare functions has been allowed but the ability to define functions has been disallowed.

like image 885
Jonathan Mee Avatar asked Apr 30 '15 11:04

Jonathan Mee


People also ask

Can you define function inside another function?

A function defined inside another function is called a nested function. Nested functions can access variables of the enclosing scope. In Python, these non-local variables are read-only by default and we must declare them explicitly as non-local (using nonlocal keyword) in order to modify them.

How do you define a function in another function?

A function which is defined inside another function is known as inner function or nested functio n. Nested functions are able to access variables of the enclosing scope. Inner functions are used so that they can be protected from everything happening outside the function.

Can I define a function inside a function in C++?

No, it's not allowed. Neither C nor C++ support this feature by default, however TonyK points out (in the comments) that there are extensions to the GNU C compiler that enable this behavior in C.

How do you define a function within another function in Python?

In Python, it is possible to pass a function as a argument to another function. Write a function useFunction(func, num) that takes in a function and a number as arguments. The useFunction should produce the output shown in the examples given below.


2 Answers

It is not obvious why one is not allowed; nested functions were proposed a long time ago in N0295 which says:

We discuss the introduction of nested functions into C++. Nested functions are well understood and their introduction requires little effort from either compiler vendors, programmers, or the committee. Nested functions offer significant advantages, [...]

Obviously this proposal was rejected, but since we don't have meeting minutes available online for 1993 we don't have a possible source for the rationale for this rejection.

In fact this proposal is noted in Lambda expressions and closures for C ++ as a possible alternative:

One article [Bre88] and proposal N0295 to the C ++ committee [SH93] suggest adding nested functions to C ++ . Nested functions are similar to lambda expressions, but are defined as statements within a function body, and the resulting closure cannot be used unless that function is active. These proposals also do not include adding a new type for each lambda expression, but instead implementing them more like normal functions, including allowing a special kind of function pointer to refer to them. Both of these proposals predate the addition of templates to C ++ , and so do not mention the use of nested functions in combination with generic algorithms. Also, these proposals have no way to copy local variables into a closure, and so the nested functions they produce are completely unusable outside their enclosing function

Considering we do now have lambdas we are unlikely to see nested functions since, as the paper outlines, they are alternatives for the same problem and nested functions have several limitations relative to lambdas.

As for this part of your question:

// This is legal, but why would I want this? int two(int bar); 

There are cases where this would be a useful way to call the function you want. The draft C++ standard section 3.4.1 [basic.lookup.unqual] gives us one interesting example:

namespace NS {     class T { };     void f(T);     void g(T, int); }  NS::T parm; void g(NS::T, float);  int main() {     f(parm); // OK: calls NS::f     extern void g(NS::T, float);     g(parm, 1); // OK: calls g(NS::T, float) } 
like image 180
Shafik Yaghmour Avatar answered Oct 14 '22 03:10

Shafik Yaghmour


Well, the answer is "historical reasons". In C you could have function declarations at block scope, and the C++ designers did not see the benefit in removing that option.

An example usage would be:

#include <iostream>  int main() {     int func();     func(); }  int func() {     std::cout << "Hello\n"; } 

IMO this is a bad idea because it is easy to make a mistake by providing a declaration that does not match the function's real definition, leading to undefined behaviour which will not be diagnosed by the compiler.

like image 34
M.M Avatar answered Oct 14 '22 05:10

M.M