2
typedef struct foo{
    void (*del)(void *toDel);
    char* (*p)(void *tp)
} Foo;

Foo init(char* (*print)(void*),void (*delFunc)(void*));

Trying to figure out how to assign or initialize the supplied parameters to the struct function pointers.

waffles
  • 71
  • 1
  • 2
  • 7

3 Answers3

4
Foo init(char* (*print)(void *toBePrinted),void (*delFunc)(void *toBeDeleted))
{
    return Foo{ .del = delFunc, .p = print};
}

What about this? Long form:

Foo init(char* (*print)(void *toBePrinted),void (*delFunc)(void *toBeDeleted))
{
    Foo tmp = {
        .del = delFunc,
        .p = print
    };
    return tmp;
}
Miroslav Mares
  • 2,292
  • 3
  • 22
  • 27
  • did you mean .del = delFunc .p = print ? – waffles Sep 10 '17 at 06:52
  • @waffles Yes, exactly, sorry – Miroslav Mares Sep 10 '17 at 06:53
  • is that a C99 or C11 standard notation? – iBug Sep 10 '17 at 07:02
  • @MahonriMoriancumer Yes it is local, but as the return type of the function is `Foo`, the `tmp` variable would be copied to the caller. If, for example, caller executes `Foo ptrs_to_fncs = init(ptr1, ptr2);`, where `ptr1` and `ptr2` are appropriate pointers to functions, then the `tmp` will be copied to the `ptrs_to_fncs` and therefore no UB. Returning structs in C works similar to returning objects in C++ - they get copied. Of course, the function `init()` can be rewritten to use dynamically allocated memory instead. – Miroslav Mares Sep 10 '17 at 07:07
  • 2
    @iBug These are **designated initializers**, introduced to C with the C99 standard, but i. e. with GCC, they can even be used in C89 and C++ as compiler extensions (even though some limitations might apply). – Miroslav Mares Sep 10 '17 at 07:10
  • Instead of returning a struct, you can pass a pointer to the struct as a function parameter. This avoids additional copying. – SBS Sep 10 '17 at 07:27
  • @SBS Yes. Here I expect compilers to inline the `Foo init(...)` function, or at least elide the copy. – Miroslav Mares Sep 10 '17 at 07:37
2

How to initialize a struct in accordance with C programming language standards

You can do it the usual way:

Return (Foo){.del=delFunc, .p=print};
Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
Maarten Arits
  • 170
  • 1
  • 9
0

The straight forward (most backward compatible approach) to define foo as Foo and initialise it is:

Foo foo = { /* Mind the order of the following initialisers!  */
  delFunc,
  print
};
alk
  • 69,737
  • 10
  • 105
  • 255