We can declare functions inside functions (I wanted a local variable, but it parses as a function declaration):
struct bvalue;
struct bdict {
bdict(bvalue);
}
struct bvalue {
explict operator bdict() const;
}
struct metainfo {
metainfo(bdict);
}
void foo(bvalue v) {
metainfo mi(bdict(v)); // parses as function declaration
metainfo mi = bdict(v); // workaround
// (this workaround doesn't work in the presence of explicit ctors)
}
Are the sole reasons "because it makes the parser simpler" and "because the standard says so", or is there an obscure use for this?
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.
It's useful if you need to use an external function whose name would conflict with an internal (static) function or variable in the current translation unit (source file). For instance (silly but it gets the point across):
static int read(int x)
{
return bar(x);
}
static int foo()
{
ssize_t read(int, void *, size_t);
read(0, buf, 1);
}
A function declaration inside another function hides other overloaded functions. e.g. Compiler error on Line 7
#include <iostream>
void f(int);
int main() {
void f(char *);
f(10); // Line 7
f("Hello world");
return 0;
}
void f(int a) {
std::cout << a;
}
void f(char *str) {
std::cout << str;
}
Are the sole reasons "because it makes
the parser simpler" and "because the
standard says so"
Yea, basically.
Everything that can be a function declaration, is a function declaration.
Unfortunately it's one of those "just is" cases.
Related
The following code cannot be compiled by VC++ and clang.
int f()
{
return 0;
}
int main()
{
// error : called object type 'int' is not a function or function pointer
int f = f();
}
It is necessary in some cases. For example, I have a function to calculate the character count of a string, which is named count, however, another function parameter is also expressively named as count.
size_t count(char* sz)
{
return strlen(sz);
}
bool check_count(char* sz, size_t count)
{
return count == count(sz); // ???
}
How to resolve this issue?
In C++ you can define a namespace for your objects, in your example you could do:
namespace MyFunctions {
int f()
{
return 0;
}
}
int main()
{
int f = MyFunctions::f();
}
The answer is simple. This is not supported. C, as many other languages, cannot support absolutely every scenario. It is unreasonable to put out such a goal. Nobody ever tried to achieve this.
In your particular case, you should rename your parameter. Function always has limited scope. It is always recompiled as a whole. Names of params in prototypes in the header files may have different names. Renaming param in the body of the function will work in 99.9999% of cases.
This question already has answers here:
Function pointer to different functions with different arguments in C
(6 answers)
Closed 9 years ago.
is there any possibility for function pointer for addressing function with different no of arguments of same return type, if not any alternate would be helpful.. thanks in advance
example:
struct method
{
char *name;
void (*ptr)(?); //? : what to define as arguments for this
};
void fun1(char *name)
{
printf("name %s\n\r",name);
}
void fun2(char *name, int a)
{
printf("name %s %d\n\r",name,a);
}
//defined before main()
method def[]=
{
{"fun1",fun1},
{"fun2",fun2}
}
//some where in main()
//call for function pointer
def[1].ptr("try", 2);
typedef void (*myfunc)(char *,int);
struct method
{
char *name;
myfunc ptr;
};
method def[]=
{
//we store fun1 as myfun
//type void(char*,int) and use it this way
{"fun1",(myfunc)fun1},
{"fun2",fun2}
};
This is by theory undefined behavior, but in reality it should work on most platforms
* edit -> this works on all plaforms just like printf(const char*,...) does.
In C, you can make your function pointer declaration read
void (*ptr)();
Which means 'A pointer to a function returning void and expecting an unspecified number of argments.'
With that adjustement, your sample program works as expected to me. However, it may well be that you're venturing into undefined (or at least implementation defined) lands here - I don't know for sure and I'm not a language lawyer (however there are plenty of language lawyers frequenting SO, so I'm sure somebody can whip up the relevant section of the standard or prove that there is none). So maybe you should rather use
/* Here be dragons! */
void (*ptr)();
instead.
Solution #1:
void fun1(char *name, ...);
void fun2(char *name, ...);
Solution #2:
method def[]=
{
{"fun1",printf},
{"fun2",printf}
}
I have a class Test with a peculiar data structure.
A member of class Test is a std::map where the key is a std::string and the mapped value is a struct defined as follows:
typedef struct {
void (Test::*f) (void) const;
} pmf_t;
Initialization of the map is OK. The problem is when I am trying to call the function pointed. I made up a toy example reproducing the problem. Here it is:
#include <iostream>
#include <map>
using namespace std;
class Test;
typedef void (Test::*F) (void) const;
typedef struct {
F f;
} pmf_t;
class Test
{
public:
Test () {
pmf_t pmf = {
&Test::Func
};
m["key"] = pmf;
}
void Func (void) const {
cout << "test" << endl;
}
void CallFunc (void) {
std::map<std::string, pmf_t>::iterator it = m.begin ();
((*it).second.*f) (); // offending line
}
std::map<std::string, pmf_t> m;
};
int main ()
{
Test t;
t.CallFunc ();
return 0;
}
Thanks in advance,
Jir
The name of the pmf_t type is f, so the first change is to remove the * to get second.f. That gives you a pointer-to-member value. To use a pointer-to-member, you need an instance. The only one you have available of the correct type is this, so use it with the ->* operator:
(this->*it->second.f)();
You need parentheses around the whole thing, or else the compiler thinks you're trying to call it->second.f() (which isn't allowed) and then applying the result to ->*.
The offending line is trying to call a member function without any object to call it on. If the intention is to call it for the this object, I believe the call should look like
( this->* ((*it).second.f) )();
Where this->* is the syntax for dereferencing a pointer-to-member for the current object. ((*it).second.f) is the pointer retrieved from the map, and () is the call operator for actually calling the function.
This is perhaps good as an exercise, but otherwise of limited use.
I think you might want to check out the C++ FAQ on this one. The syntax is apparently pretty tricky to get right (they actually recommend using a macro).
It might be too late for this question but, the seemingly complex synatax can be break down to two simple lines so it looks pretty clear:
void CallFunc (void)
{
pmf_t t = m["key"]; //1>get the data from key
(this->*t.f)(); //2>standard procedure to call pointer to member function
}
try this:
(this->*((*it).second.f)) ();
I have the following code which works as expected:
#include <iostream>
using namespace std;
typedef int (TMyFunc)(int);
TMyFunc* p;
int x(int y)
{
return y*2;
}
int main()
{
p = &x;
cout << (*p)(5) << endl;
}
What I want to do is skip defining x and define p there straight. Something like
TMyFunc p; p(y){return y*2;}.
Is that possible? If so how do I do it? If not why?
EDIT:
After seeing the answers, I think I should clarify: I want the definition to be separate. i.e. function definition will be in a shared object. An application will acquire a function pointer to the function via dlsym. I do not want a function object. What I want is to know if I can define a function using its type which a header file common to both the shared object and the application will provide. I hope that came out right :).
EDIT2: For sbi :)
This resides in a header which is included in both the application and the shared object:
#define FNAME_GET_FACTORY "GetFactory"
#define FNAME_GET_FUNCTION_IDS "GetFunctionIDs"
#define FNAME_GET_PLUGIN_INFO "GetPluginInfo"
typedef FunctionFactory* (*TpfGetFactory)();
typedef size_t (*TpfGetFunctionIDs)(int**);
typedef PluginInfo* (*TpfGetPluginInfo)();
In the application, something like this happens:
TpfGetFactory pF = (TpfGetFactory)dlsym(pHandle, FNAME_GET_FACTORY);
//Use pF for anything
Now, to do this, I have to define GetFactory as follows in the shared object:
extern "C" FunctionFactory* FNAME_GET_FACTORY(){//CODE}
Forgetting the extern "C" part for now, Can I define this function using the type TpfGetFactory which is already defined? (This is not a huge issue I know - but I am curious as to whether it is possible :) ). What I want is something like this in the shared object :
TpfGetFactory f;
f(){//Implementation}
EDIT3:
My try:
#include <iostream>
using namespace std;
typedef int (TF)(int);
TF f;
f(int x)
{
return x*2;
}
int main()
{
x(3);
}
main.cpp:9: error: ISO C++ forbids declaration of ‘f’ with no type
main.cpp: In function ‘int main()’:
main.cpp:16: error: ‘x’ was not declared in this scope
It's possible in C++1x, the next C++ standard, generally expected next year (which would make it C++11, then). It allows this:
auto p = [](int y){return y*2;};
This relies on auto been given a new meaning ("automatically deduce the type of this variable from the expression that initializes it") and the new lambda functions (allowing to create functions on the fly).
Your compiler might actually already support this.
This works fine for me, with the current C++03 Standard:
typedef int (TMyFunc)(int);
TMyFunc* p;
int test()
{
struct LocalClass
{
static int functionLocal(int y)
{
return 2;
};
};
LocalClass localClass;
p = &(LocalClass::functionLocal);
}
But maybe it happens to be more complicated to write than what you wanted to simplify ;-),
however it works and you can define your functions in place, locally.
Here is some documentation about local classes
This will be possible in the next C++ standard, via lambdas. In the current standard, however, it is impossible to define one function inside another.
Not directly in C++98.
For standard C++, that is C++98, check out e.g. the Boost Lambda library. It lets you write expressions like
for_each(a.begin(), a.end(), std::cout << _1 << ' ');
C++0x adds direct support for lambda expressions.
Cheers & hth.,
Could someone please tell me if this is possible in C or C++?
void fun_a();
//int fun_b();
...
main(){
...
fun_a();
...
int fun_b(){
...
}
...
}
or something similar, as e.g. a class inside a function?
thanks for your replies,
Wow, I'm surprised nobody has said yes! Free functions cannot be nested, but functors and classes in general can.
void fun_a();
//int fun_b();
...
main(){
...
fun_a();
...
struct { int operator()() {
...
} } fun_b;
int q = fun_b();
...
}
You can give the functor a constructor and pass references to local variables to connect it to the local scope. Otherwise, it can access other local types and static variables. Local classes can't be arguments to templates, though.
C++ does not support nested functions, however you can use something like boost::lambda.
C — Yes for gcc as an extension.
C++ — No.
you can't create a function inside another function in C++.
You can however create a local class functor:
int foo()
{
class bar
{
public:
int operator()()
{
return 42;
}
};
bar b;
return b();
}
in C++0x you can create a lambda expression:
int foo()
{
auto bar = []()->int{return 42;};
return bar();
}
No but in C++0x you can http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions which may take another few years to fully support. The standard is not complete at the time of this writing.
-edit-
Yes
If you can use MSVC 2010. I ran the code below with success
void test()
{
[]() { cout << "Hello function\n"; }();
auto fn = [](int x) -> int { cout << "Hello function (" << x << " :))\n"; return x+1; };
auto v = fn(2);
fn(v);
}
output
Hello function
Hello function (2 :))
Hello function (3 :))
(I wrote >> c:\dev\loc\uniqueName.txt in the project working arguments section and copy pasted this result)
The term you're looking for is nested function. Neither standard C nor C++ allow nested functions, but GNU C allows it as an extension. Here is a good wikipedia article on the subject.
Clang/Apple are working on 'blocks', anonymous functions in C! :-D
^ ( void ) { printf("hello world\n"); }
info here and spec here, and ars technica has a bit on it
No, and there's at least one reason why it would complicate matters to allow it. Nested functions are typically expected to have access to the enclosing scope. This makes it so the "stack" can no longer be represented with a stack data structure. Instead a full tree is needed.
Consider the following code that does actually compile in gcc as KennyTM suggests.
#include <stdio.h>
typedef double (*retdouble)();
retdouble wrapper(double a) {
double square() { return a * a; }
return square;
}
int use_stack_frame(double b) {
return (int)b;
}
int main(int argc, char** argv) {
retdouble square = wrapper(3);
printf("expect 9 actual %f\n", square());
printf("expect 3 actual %d\n", use_stack_frame(3));
printf("expect 16 actual %f\n", wrapper(4)());
printf("expect 9 actual %f\n", square());
return 0;
}
I've placed what most people would expect to be printed, but in fact, this gets printed:
expect 9 actual 9.000000
expect 3 actual 3
expect 16 actual 16.000000
expect 9 actual 16.000000
Notice that the last line calls the "square" function, but the "a" value it accesses was modified during the wrapper(4) call. This is because a separate "stack" frame is not created for every invocation of "wrapper".
Note that these kinds of nested functions are actually quite common in other languages that support them like lisp and python (and even recent versions of Matlab). They lead to some very powerful functional programming capabilities, but they preclude the use of a stack for holding local scope frames.
void foo()
{
class local_to_foo
{
public: static void another_foo()
{ printf("whatevs"); }
};
local_to_foo::another_foo();
}
Or lambda's in C++0x.
You can nest a local class within a function, in which case the class will only be accessible to that function. You could then write your nested function as a member of the local class:
#include <iostream>
int f()
{
class G
{
public:
int operator()()
{
return 1;
}
} g;
return g();
}
int main()
{
std::cout << f() << std::endl;
}
Keep in mind, though, that you can't pass a function defined in a local class to an STL algorithm, such as sort().
int f()
{
class G
{
public:
bool operator()(int i, int j)
{
return false;
}
} g;
std::vector<int> v;
std::sort(v.begin(), v.end(), g); // Fails to compile
}
The error that you would get from gcc is "test.cpp:18: error: no matching function for call to `sort(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, f()::G&)'
"
It is not possible to declare a function within a function. You may, however, declare a function within a namespace or within a class in C++.
Not in standard C, but gcc and clang support them as an extension. See the gcc online manual.
Though C and C++ both prohibit nested functions, a few compilers support them anyway (e.g., if memory serves, gcc can, at least with the right flags). A nested functor is a lot more portable though.
No nested functions in C/C++, unfortunately.
As other answers have mentioned, standard C and C++ do not permit you to define nested functions. (Some compilers might allow it as an extension, but I can't say I've seen it used).
You can declare another function inside a function so that it can be called, but the definition of that function must exist outside the current function:
#include <stdlib.h>
#include <stdio.h>
int main( int argc, char* argv[])
{
int foo(int x);
/*
int bar(int x) { // this can't be done
return x;
}
*/
int a = 3;
printf( "%d\n", foo(a));
return 0;
}
int foo( int x)
{
return x+1;
}
A function declaration without an explicit 'linkage specifier' has an extern linkage. So while the declaration of the name foo in function main() is scoped to main(), it will link to the foo() function that is defined later in the file (or in a another file if that's where foo() is defined).