11

First of all, I've googled the error and read these answers:

But none of them helped me, so here we are.

The problem resides somewhere in between these 2 structures, prx_data_s which store generic data and prx_ops_s that defines pointers to functions that will use that data.

I'll simplify the sources for the example:

prx_data.h

#ifndef PRX_EXAMPLE_DATA_H
#define PRX_EXAMPLE_DATA_H

#include "prx_ops.h"

struct prx_data_s {
    enum  prx_op_t op;
    char *keyquery;
};

char *get_query(struct prx_data_s *dt);

#endif

prx_data.c

#include "prx_data.h"

char *get_query(struct prx_data_s *dt)
{
    return dt->keyquery;
}

prx_ops.h

#ifndef PRX_EXAMPLE_OPS_H
#define PRX_EXAMPLE_OPS_H

#include "prx_data.h"

enum prx_op_t {
    PRX_EXAMPLE_OP = 2
};

struct prx_ops_s {
    int (*dec) (struct prx_data_s *);
};

#endif

I'm trying to compile the object from the above example with:

clang -c prx_data.c -o prx_data.o -std=c11 -g -Wall

And this is the output error:

In file included from prx_data.c:1:
In file included from ./prx_data.h:4:
./prx_ops.h:11:24: warning: declaration of 'struct prx_data_s' will not be visible outside of this function [-Wvisibility]
int (*dec) (struct prx_data_s *);
                   ^

All help is welcome, thanks :)

criw
  • 587
  • 1
  • 5
  • 15
  • 7
    You have a circular include graph - prx_ops includes prx_data and vice versa. Although the include guards break any infinite loop, in your example the ops header gets read first, resulting in a forward declaration of the struct. – TypeIA Aug 23 '18 at 12:25
  • Oh, I didn't knew circular dependencies were a thing, it makes sense. Thanks @TypeIA! – criw Aug 23 '18 at 12:32
  • in general, as you found out, you should not define functions within a header file – user3629249 Aug 24 '18 at 00:05

2 Answers2

7

You have a problem with circular dependencies in your header:

prx_data.h:

#include "prx_ops.h" <<< Here we do not yet see the struct definition

    prx_ops.h:

    #include "prx_data.h"  <<<< Nothing will be included due to inclusion guards.

    struct prx_ops_s {
       int (*dec) (struct prx_data_s *);  <<<< Here a new struct type is declared.
    };

later back in prx_data.h:

struct prx_data_s {
  enum  prx_op_t op;
  char *keyquery;
};
Gerhardh
  • 11,688
  • 4
  • 17
  • 39
  • I didn't knew circular dependencies were a thing, it makes completely sense. Thanks! I'll accept the answer as soon as I can – criw Aug 23 '18 at 12:33
4

When reading prx_ops.h, you dont 't have prx_data.h included because the compiler is reading prx_ops.h from the include at the beginning of prx_data.h. You thus have to forward declare it.

Try adding

struct prx_data_s;

at the beginning of prx_ops.h`

Hope that helps ~~

Yanis.F
  • 612
  • 6
  • 18