Live data from Hacker News

How Do I Declare a Function Pointer in C?

fuckingfunctionpointers.com

91–100 of 111 posts

Re: How Do I Declare a Function Pointer in C?

#91

Earlier quoted context omitted.

19 years as a C/C++/ObjC developer, and this never occurred to me. And it works with C Blocks! typedef int IntegerProcessor(int); int executeTheFunctionPointer(IntegerProcessor* function) { return function(23); } int executeTheBlock(IntegerProcessor^ block) { return block(32); } int doubler(int a) { return a * 2; } int main(int argc, const char * argv[]) { IntegerProcessor* myFunctionPtr = &doubler; int a = executeTh…

This is so cool. Where can I find documentation on the following? IntegerProcessor^ myBlock = ^(int b) { return a * b; }; I wasn't aware C supported nested functions.

There's a GNU extension for it.

https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html

But it's not a proper closure, and it's not GC'd, so it's pretty useless.

Re: How Do I Declare a Function Pointer in C?

#92
post #48
post #46

Earlier quoted context omitted.

And yet so many people learn int* p; // p is an int pointer instead of int *p; // dereferencing p will give an int I know this is the subject of holy wars, but once I'd seen the second one my eyes were opened and I had way less trouble. I think that declaration follows use is another of example of the amazing design powers of the patriarchs.

> amazing design powers of the patriarchs Thanks for elevating their gender specifically.... gosh forbid that Ada had any amazing design powers.

Thanks for caring about gendered language. I used this term because it's used (humorously) in the Unix Koans[0]. But maybe you're reading to far into it, I certainly don't mean to imply their gender had anything to do with C's design, but for better or worse they did happen to be men and were seen by by some as a "father figure" for the language.

[0]http://catb.org/esr/writings/unix-koans/zealot.html

Re: How Do I Declare a Function Pointer in C?

#93
post #91

Earlier quoted context omitted.

This is so cool. Where can I find documentation on the following? IntegerProcessor^ myBlock = ^(int b) { return a * b; }; I wasn't aware C supported nested functions.

There's a GNU extension for it. https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html But it's not a proper closure, and it's not GC'd, so it's pretty useless.

Last time I checked, Clang doesn't support nested functions although it supports most of GNU extensions (or similar features with slightly altered syntax).

I'm not 100% sure what you mean by "proper closure" but it does capture variables from the outer scope. It has limitations with scopes and lifetimes, of course.

Re: How Do I Declare a Function Pointer in C?

#94
The easiest and best way to learn the syntax is to not memorise specific cases but the grammar itself, which IMHO is no more difficult than the existing concept of operator precedence. Everyone using C should hopefully already know that multiplication has higher precedence than addition, so likewise function call (and array subscripting) has higher precedence than pointer dereference. Thus this table should make it clear that combining the two operators creates pointer-to-function:

    T x;                      T *y;
    T f();                    T (*g)();

    T                         pointer to T
    function returning T      pointer to function returning T
and the alternative, T h(); , is parsed as T (h()); and thus becomes "function returning pointer to T".

The apparent struggle I see with this syntax has always somewhat puzzled me, because I don't see the same level of complaints about e.g. arithmetic expressions (like 6+3*4/(2+1)) which are parsed with precedence in much the same way. K&R even has a section on writing a parser that recognises this syntax, so I suspect it's really not that hard, but the perception spread by those who didn't learn the syntax but only memorised the "easy cases" is making it appear more difficult than it really is.

Re: How Do I Declare a Function Pointer in C?

#96
post #80
post #79

Earlier quoted context omitted.

What if I told you that even declarations like char const *(* const (*(*ip)())[])[] are trivial to read? [Read this]( http://www.icce.rug.nl/documents/cplusplus/cplusplus03.html#... ) and you'll never struggle with any declaration ever again.

"Unambiguous" is not the same as "trivial". C code generally reads left to right, so a trivial syntax for declaring, say, an array of const pointers to functions that take a const pointer to a char and return a const pointer to a char, would have tokens for those things in that order.

C code generally reads left to right

No it doesn't:

    p += k[foo(bar, baz, 3*(quux+1))] 

Re: How Do I Declare a Function Pointer in C?

#97
post #93
post #91

Earlier quoted context omitted.

There's a GNU extension for it. https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html But it's not a proper closure, and it's not GC'd, so it's pretty useless.

Last time I checked, Clang doesn't support nested functions although it supports most of GNU extensions (or similar features with slightly altered syntax). I'm not 100% sure what you mean by "proper closure" but it does capture variables from the outer scope. It has limitations with scopes and lifetimes, of course.

Proper closures require "fat pointers", basically you're storing two pointers, one to the function and one to its context data. (In the case of a nested function that's its stackframe.) They also require that stackframes be generally allocated on the heap.

C doesn't have a type for that, it only has function pointers, which only have space for a single pointer. So what GCC does is actually a horrible hack - it dynamically creates a function (called a trampoline), which calls the actual function with a pointer to its data. But because GCC doesn't have true closures, and only refers to the surrounding function's existing stackframe, which is on the stack, not the heap, this only works until the surrounding function has returned. And since the trampoline is also allocated on the stack, this requires the stack to be executable, which is Not Great for security.

Re: How Do I Declare a Function Pointer in C?

#99

The easiest and best way to learn the syntax is to not memorise specific cases but the grammar itself, which IMHO is no more difficult than the existing concept of operator precedence. Everyone using C should hopefully already know that multiplication has higher precedence than addition, so likewise function call (and array subscripting) has higher precedence than pointer dereference. Thus this table should make it c…

Nice explanation, thanks; your formatting got a little messy right after the code block, though, because things between asterisks are rendered cursive.

Re: How Do I Declare a Function Pointer in C?

#100
post #83
post #78

Every time I have to deal with the declarator syntax in C or C++, I can't help but ponder what K&R were thinking when they designed this. It's not like there weren't other languages back then with a saner approach. It looks like what they did was take the syntax from B: auto x[10]; and generalize it such that the type name ended up before the variable name, as in Algol. But in B this worked much better, because it di…

What they were thinking can be see in K&R C - there is no "typedef" in early C. Without typedef, the syntax of C is context-independent and LALR-1. You don't have to know if a name is a type to parse the syntax. Then came "typedef", which broke parsing. C parsing became context-dependent. To parse C with "typedef", and especially C++, you must read all the header files first. With name-first declaration syntax (Pasca…

That's interesting -- I was wondering in which cases typedef changes the parse tree, and came across a few [1]:

    a (b);      /* function call or declaration */
    a * b;      /* multiplication or declaration */
    f((a) * b); /* multiplication or deref and cast */
> With one further change, namely deleting the production typedef-name: identifier and making typedef-name a terminal symbol, this grammar is acceptable to the YACC parser-generator.

[1] http://eli.thegreenplace.net/2007/11/24/the-context-sensitiv...

Post reply on HN