Function returning pointer to itself

J

John Turner

typedef void (*vfp)();
typedef vfp (*fp)();

static fp hello()
{
printf("Hello.\n");
return (fp)&hello;
}

main(){
hello()()();
}

Here we have a function that returns a fp, which is a function pointer
typedef, the function of which returns a vfp, which is another function
pointer typedef but which returns void, so we can use hello()()(); but
not hello()()()(); unless we have a cast. I was wondering if there's a
way to do this properly with some kind of properly recursive typedef. I
saw an example of how to do this fairly "nicely" in C++ but couldn't
find anything for C itself. Anyone here know how to do this? Purely
theoretical by the way, wouldn't want to release this on some poor,
unsuspecting, real project.

Cheers,
John
 
G

Guest

John said:
typedef void (*vfp)();
typedef vfp (*fp)();

static fp hello()
{
printf("Hello.\n");
return (fp)&hello;
}

main(){
hello()()();
}

This is not valid C. hello() is declared as returning 'fp', and you
call it through a pointer to a function returning 'vfp'. As far as
standard C is concerned, the behaviour is undefined. There are other
problems with the code too: you're calling printf without including
<stdio.h>, and you're using implicit int and unprototyped functions.
The first was never valid, the second is no longer valid, the third is
a bad idea as it makes it difficult for compilers to check the argument
types for you.
Here we have a function that returns a fp, which is a function pointer
typedef, the function of which returns a vfp, which is another function
pointer typedef but which returns void, so we can use hello()()(); but
not hello()()()(); unless we have a cast. I was wondering if there's a
way to do this properly with some kind of properly recursive typedef.

This is a FAQ:
http://c-faq.com/decl/recurfuncp.html

#include <stdio.h>
struct fp {
struct fp (*fp)(void);
};
struct fp hello(void) {
struct fp ret = { hello };
printf("Hello.\n");
return ret;
}
int main(void) {
hello().fp().fp().fp().fp().fp().fp();
return 0;
}
 
R

Rg

John said:
typedef void (*vfp)();
typedef vfp (*fp)();
static fp hello()
{
printf("Hello.\n");
return (fp)&hello;
}
main(){
hello()()();
}

This is not valid C. hello() is declared as returning 'fp', and you
call it through a pointer to a function returning 'vfp'. As far as
standard C is concerned, the behaviour is undefined. [...]

An alternative explanation:

hello() evaluates to an expression of type fp, which is also vfp (*)()
or void (*(*)())()

hello()() evaluates to vfp, which is also void (*)()

hello()()() evaluates to void

Finally, hello()()()() leads to syntax error it is an attempt to
perform a function call over an object of type void.
 
J

John Turner

Harald said:
This is not valid C. hello() is declared as returning 'fp', and you
call it through a pointer to a function returning 'vfp'. As far as
standard C is concerned, the behaviour is undefined. There are other
problems with the code too: you're calling printf without including
<stdio.h>, and you're using implicit int and unprototyped functions.
The first was never valid, the second is no longer valid, the third is
a bad idea as it makes it difficult for compilers to check the argument
types for you.

This is a FAQ:
http://c-faq.com/decl/recurfuncp.html

#include <stdio.h>
struct fp {
struct fp (*fp)(void);
};
struct fp hello(void) {
struct fp ret = { hello };
printf("Hello.\n");
return ret;
}
int main(void) {
hello().fp().fp().fp().fp().fp().fp();
return 0;
}

I'm sorry some of the C wasn't valid. I was aware of the hello()
declaration being fundamentally wrong and forgetting stdio.h and the
implicit int declaration of main was just right out. Thanks for
pointing me to the FAQ answer, I hadn't found that before (I've looked
through some of that FAQ, but missed that one...). I'd managed to
implement this using structs too, but was hoping to be able to use it
with the syntax of hello()()()()() just out of interest. It makes sense
to me that it's not possible now though.
 

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
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top