2

Recently I found out that it is possible to pass an implicit array to a function by casting it in the function call

void foo(int* array);
foo((int[4]) {1,2,3,4});

However, I was wondering if it was possible to do the same thing when passing a function pointer to a function, so something like:

void bar(void (*foobar)(void));
bar((void) {printf("foobar\n");});

So Is it even possible to do this?

The reason I want to know is that if I have a large block of code which may have a certain loop structure, but the core functionality changes between instances, I don't want to have to litter my code with multiple temporary functions just to pass them to another function. Hence wanting to be able to define the temporary function in the parameters.

Many thanks

DiJuMx
  • 524
  • 5
  • 10

3 Answers3

5

No, not in standard C. You have two non-standard alternatives, though:

One. GCC's "nested functions" extension (GCC only):

void call(void (*fn)())
{
    fn();
}

void somefunc()
{
    void tmp_func()
    {
        printf("Hello world!\n");
    }
    call(tmp_func);
}

Two, Apple's blocks (recent GCC and Clang):

void call(void (^blk)())
{
    blk();
}

call(^{
    printf("Hello world!\n");
});
  • As an aside to the first method, there's also the some macros (and explanations) in this answer: http://stackoverflow.com/questions/10405436/anonymous-functions-using-gcc-statement-expressions - not to mention the slightly more nuts version here: http://en.wikipedia.org/wiki/Anonymous_function#C_lambda_expressions – slugonamission Feb 23 '13 at 19:40
  • @slugonamission Let's not hack with the preprocessor :) –  Feb 23 '13 at 19:40
  • fair enough :) - I just found them interesting when poking around for this answer. I tend to take the line that if you don't understand the macro, you probably shouldn't have it in your code though :) – slugonamission Feb 23 '13 at 19:43
  • @slugonamission [I have written an ugly hack](https://github.com/H2CO3/libblock) to make old GCC versions "support" blocks, and I hate it. –  Feb 23 '13 at 19:44
  • 1
    ouch. That's quite something – slugonamission Feb 23 '13 at 19:45
1

The "implicit array" is actually a compound literal and it's C99 specific.

Anonymous functions on the other hand can't be achieved using standard C. If you use GNU GCC, you could mimic them using two extensions:

  1. Nested Functions
  2. Statement expressions

First create a wrapper macro:

#define lambda(return_type, body)     \
({                                    \
    return_type lambda_function body; \
    lambda_function;                  \
})

Then you can use it like this

bar(lambda(void, (void)
    {
        printf("foobar\n");
    })
);
Avidan Borisov
  • 3,235
  • 4
  • 24
  • 27
0

The functionality you're looking for is not part of the C standard. However, this is exactly the problem (or one of the problems) that blocks — an Apple extension to the standard — were designed to fix. If you're compiling for OS X 10.5 or later (or using clang with a Blocks runtime on other supported platforms; see mackyle/blocksruntime), you can change your code to something like this:

void bar(void (^foobar)(void));

And invoke like this:

bar(^{
    printf("foobar\n");
});
Matt Patenaude
  • 4,497
  • 1
  • 22
  • 21