Local Functions...

D

deepakvsoni

Why does C++ restrict definition of functions with in functions?
int f1() {
int f2() {
.....
}
} //This is not supported.

Thanks in advance to anybody who replies..
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

Why does C++ restrict definition of functions with in functions?
int f1() {
int f2() {
.....
}
} //This is not supported.

Thanks in advance to anybody who replies..

I have not studied the idea in detail but I can't come up with anything
that can be accomplished with nested functions that can't be done with
normal functions. In fact I find it a bit limiting since f2() can't be
called from a scope outside f1(), which means that you can't reuse f2()
in some other context.
 
M

Matthias Pfeifer

Erik said:
I have not studied the idea in detail but I can't come up with anything
that can be accomplished with nested functions that can't be done with
normal functions. In fact I find it a bit limiting since f2() can't be
called from a scope outside f1(), which means that you can't reuse f2()
in some other context.


you could feed f2 into some std::algorithm

int f1() {
void f2(double* ptr) {
.....
}
std::for_each(ptr, ptr+N, f2);
}

here the definition of f2 is local to the (probably) single place where
it is used.

matthias
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

you could feed f2 into some std::algorithm

int f1() {
void f2(double* ptr) {
.....
}
std::for_each(ptr, ptr+N, f2);
}

here the definition of f2 is local to the (probably) single place where
it is used.

Yes, but applications change (so I might need f2() in some other place
later on) and I didn't really gain much by not having f2() in a wider
scope (such as a namespace or a class).
 
R

Richard Herring

Erik Wikström said:
I have not studied the idea in detail but I can't come up with anything that
can be accomplished with nested functions that can't be done with
normal functions.

Nested functions would, in principle, have access to the local variables
of their containing function:

int f1() {
int i;
int f2() {
int j = i;
/* do stuff */
}
i = 1;
f2();
i = 2;
f2();
}


Making this work in practice, where the inner function might be invoked
recursively or indirectly, involves an extra level of indirection, which
means more work for the compiler and a potential performance hit at
runtime. Some languages (e.g. Pascal and some of the Algol family IIRC)
allow this; C and C++ follow their parent BCPL by simply banning such
things (actually BCPL allowed nested function definitions but outlawed
access to the parent function's local variables, so all the nested
declaration achieved was to reduce the scope of the inner function.)
In fact I find it a bit limiting since f2() can't be called from a scope outside
f1(),

In the example above, what would f2() use for "i" ?
which means that you can't reuse f2() in some other context.

That's called "encapsulation" and is normally regarded as a Good Thing
;-)
 
V

Victor Bazarov

Matthias said:
you could feed f2 into some std::algorithm

int f1() {
void f2(double* ptr) {
.....
}
std::for_each(ptr, ptr+N, f2);
}

here the definition of f2 is local to the (probably) single place
where it is used.

What problem does making it local solve that cannot be solved by
just having the function normal, outside of 'f1' body?

V
 
W

werasm

Matthias said:
you could feed f2 into some std::algorithm

This little piece of code compiles, and does something similar,
not that its of any use... It compiles under all of the
compilers I've checked, but I don't know whether its
compliant. I Nested classes can't be template parameters,
but <exec()> is a static function - a true nested function,
it would seem.

#include <algorithm>
#include <vector>

int main()
{
struct local
{
static void exec( int ){}
};

std::vector<int> v( 10, 10 );
std::for_each( v.begin(), v.end(), &local::exec );

return 0;
}

Regards,

Werner.
 
W

werasm

Why does C++ restrict definition of functions with in functions?
int f1() {
int f2() {
.....
}
} //This is not supported.

See my other reply. It does seem possible with that "hack", if
compliant.

Werner
 
W

werasm

werasm said:
#include <algorithm>
#include <vector>

int main()
{
struct local
{
static void exec( int ){}
};

std::vector<int> v( 10, 10 );
std::for_each( v.begin(), v.end(), &local::exec );

return 0;
}

Regards,

Werner.

Could anybody please comment on whether this is standard compliant.
I've
found the following:

Par 9.8.4:
A Local class shall not have static data members.

I suppose a static member function does not fall into this category???

Regards,

Werner
 
V

Victor Bazarov

werasm said:
Could anybody please comment on whether this is standard compliant.

It's not.
I've
found the following:

Par 9.8.4:
A Local class shall not have static data members.

I suppose a static member function does not fall into this category???

What category?

Also, see [temp.arg.type]/2. A local class has no linkage.

You've apparently run into extensions in all compilers you've used.

V
 
J

Joe Greer

werasm said:
Could anybody please comment on whether this is standard compliant.
I've
found the following:

Par 9.8.4:
A Local class shall not have static data members.

I suppose a static member function does not fall into this category???

Local classes aren't supposed to have external linkage. I would guess that static
data/functions would cause there to be external linkage and therefore not allowed.

joe
 
A

Abdo Haji-Ali

Why does C++ restrict definition of functions with in functions?
Because C++ has classes. Really, why would you need such function-level
encapsulation when you can do a more logical and defined class
encapsulation, I wonder?
 
O

osmium

Why does C++ restrict definition of functions with in functions?
int f1() {
int f2() {
.....
}
} //This is not supported.

Your best place to find an answer is in comp.std.c++. They should be
willing to discuss the evolution of the standard, it is a moderated group so
anticipate a lot of delay before you get an answer.

My guess is that it makes the writing of compilers simpler and more
manageable. Remember that the C++ evolved from simple roots. I much prefer
the alternative form you suggest.
 
V

Victor Bazarov

Alf said:
* Victor Bazarov:

Chapter & verse, please.

You made me think a bit (tsk-tsk).

[basic.link]/2, last bullet item.
[temp.arg.type]/2.

Since the name of a member of the local type cannot be referred to
from other modules (or from other scopes in the same module), it has
no linkage. As such it cannot appear as a type template argument.
However, in this particular situation, if the type of the second
argument of 'for_each' template is deduced to be "a function pointer"
and not "a member of 'local' class", then it's probably OK. I don't
know which what it would fall, though.

V
 
B

Bo Persson

osmium wrote:
::
::: Why does C++ restrict definition of functions with in functions?
::: int f1() {
::: int f2() {
::: .....
::: }
::: } //This is not supported.
::
:: Your best place to find an answer is in comp.std.c++. They should
:: be willing to discuss the evolution of the standard, it is a
:: moderated group so anticipate a lot of delay before you get an
:: answer.
::
:: My guess is that it makes the writing of compilers simpler and more
:: manageable. Remember that the C++ evolved from simple roots. I
:: much prefer the alternative form you suggest.

The short answer is that it was not allowed in C, and nobody bothered
to add it to C++. In C++ you can put f1() and f2() in the same class,
possibly making f2 private, and they can then share the class' member
variables.



Bo Persson
 
W

werasm

Victor said:
You made me think a bit (tsk-tsk).

[basic.link]/2, last bullet item.
[temp.arg.type]/2.

I've looked at these references, and I agree with the fact that the
static member function should have no linkage. I could not for
certain decide whether function pointers where treated differently (In
fact, I also think it should fail).

Pointers to local class members <int X::*f> certainly does not work
for
exactly the reason you've mentioned. Perhaps it works because the
argument is deduced by the function template (14.8.8), although,
attempting to do the same with pointers to member functions fails
with error:

"a template argument may not reference a local type"

I've performed compilations with later version of GCC, Comeau and
the compilers offered at www.dinkumware.com, all with the same
result. For comeau I've used --strict as option.

Thanks for response,

Regards,

Werner
 
A

Alf P. Steinbach

* werasm:
Victor said:
You made me think a bit (tsk-tsk).

[basic.link]/2, last bullet item.
[temp.arg.type]/2.

I've looked at these references, and I agree with the fact that the
static member function should have no linkage. I could not for
certain decide whether function pointers where treated differently (In
fact, I also think it should fail).

Pointers to local class members <int X::*f> certainly does not work
for
exactly the reason you've mentioned. Perhaps it works because the
argument is deduced by the function template (14.8.8), although,
attempting to do the same with pointers to member functions fails
with error:

"a template argument may not reference a local type"

I've performed compilations with later version of GCC, Comeau and
the compilers offered at www.dinkumware.com, all with the same
result. For comeau I've used --strict as option.

It's very simple.

You can't use a local class as a template argument, directly or
indirectly. A member function pointer includes the relevant class as
part of its type. Hence you cannot use that, when the class is local.

But you can use the type of any pure function pointer as template
argument, as long as the function signature doesn't refer to a local
class, because nothing in that function pointer type refers to a local
class. In the example that appeared earlier only the function pointer's
type was used at compile time, the function pointer value was used at
run time. If you tried to use the function pointer value at compile
time you should get an error with a conforming compiler, because in that
case the function needs to have external linkage, and if you made the
function signature refer to the local class you should also get error.

Cheers, & hth.,

- Alf
 
T

tragomaskhalos

Why does C++ restrict definition of functions with in functions?
int f1() {
int f2() {
.....
}

} //This is not supported.

Many of these "why doesn't C++ allow ...?" type questions
have been answered by Stroustrup in print, and this is no
exception. That said, I cannot track down the great man's
explanation for this case, but vaguely recall it has
something to do with accessibility of variables in the
enclosing scope (ie f1 here) requiring an extra context
pointer getting passed around, which would be an
unacceptable overhead; and this is precisely the reason
that others in this thread have already alluded to.
 
J

Juha Nieminen

Erik said:
I have not studied the idea in detail but I can't come up with anything
that can be accomplished with nested functions that can't be done with
normal functions. In fact I find it a bit limiting since f2() can't be
called from a scope outside f1(), which means that you can't reuse f2()
in some other context.

I can't come up with anything that can be accomplished with private
member functions and variables that can't be done with normal global
functions and variables. In fact I find it a bit limiting since such
a private member function or variable can't be called from a scope
outside the class, which means that you can't reuse the function or
variable in some other context.

(And for those who didn't get it: Yes, the above is sarcasm.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,201
Messages
2,571,049
Members
47,655
Latest member
eizareri

Latest Threads

Top