0

I have a struct which has a function pointer as a member variable. The function pointer takes a pointer to the struct as one of its parameters.

By looking at solutions posted on here for such circular dependencies I used a forward declaration to be able to compile.

I still have the problem of not being able to initialize the struct. Posted below is the code and the output.

edit: My earlier MVCE didn't reproduce the problem correctly. I can get this to compile by naming the struct instead of just having a struct alias. Not exactly sure why though.

#include "stdio.h"

//Forward declaration
struct data;

typedef int(*funcPtr) (struct data* a);

typedef struct
{
    int a;
    int b;
    funcPtr foo;
}data;

int foo(data* pData)
{
    return 0;
}

static data testData[] = {{1,1,foo}, {0,2,foo},};

int main()
{
    printf("Just trying to compile this program\n");
    return 0;
}

Error output --

compileError.c:20:1: warning: initialization from incompatible pointer type [enabled by default]
static data testData[] = {{1,1,foo}, {0,2,foo},};
^
compileError.c:20:1: warning: (near initialization for \u2018testData[0].foo\u2019) [enabled by default]
compileError.c:20:1: warning: initialization from incompatible pointer type [enabled by default]
compileError.c:20:1: warning: (near initialization for \u2018testData[1].foo\u2019) [enabled by default
sdmello
  • 431
  • 2
  • 6
  • 14
  • 2
    Side note: It doesn't show in your example code, but your struct isn't `struct data`. It is an unnamed struct type-aliassed to `data`. – M Oehm Apr 08 '16 at 06:01
  • This actually solved the problem I had in my original code. This MVCE code just had a typo which led to other answers. Thank you! – sdmello Apr 08 '16 at 06:13
  • 1
    Your `typedef struct { … } data;` defines an alias `data` for an untagged structure type. That type is unrelated to the `struct data` you mentioned earlier. You need `typedef struct data { … } data;` to get the code to compile. As amended, this is a duplicate of quite a lot of other questions. Understanding `struct tag { … }` vs `typedef struct { … } tag` seems to be a fairly common problem. – Jonathan Leffler Apr 10 '16 at 16:31

2 Answers2

2

Function foo is incompatible with funcPtr - it returns an int, not a void.

Also, your variable is declared as an array, but you initialize it with a single value - remove the [].

Amit
  • 45,440
  • 9
  • 78
  • 110
  • You can have arrays with one element, but you should fully brace your initializer: `data testData[] = { { 1, 1, foo }, };`. This may be a side-effect of converting the real program into an MCVE. – Jonathan Leffler Apr 08 '16 at 05:54
  • @JonathanLeffler - It seems to me an array was not intentionally used here. – Amit Apr 08 '16 at 05:56
  • Yeah I should have probably used multiple values. My real program uses an array. – sdmello Apr 08 '16 at 05:57
  • @coder_mario: ideally, you would have indicated that you intended an array by using the extra level of braces, or a comment such as `/* ... */` after the elements you provided. You did a good job on minimization; almost too good. – Jonathan Leffler Apr 08 '16 at 06:09
  • Thanks, though this MVCE kinda induced its own bug which didn't let me totally reproduce the issue I had. The comment on the question actually led me to the fix. – sdmello Apr 08 '16 at 06:16
1

You define an array of struct data but initialize it with just one element. If this was unintentional, remove '[]':

data testData = {1,1,foo};

If an array is needed, initialize with a fully-braced array initializer:

data testData[] = { {1,1,foo} };

Also, check your member function signature. The declaration and the implementation should both return either void or int.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Harvey Pham
  • 623
  • 4
  • 17