Is there a way to share the “structure” between the source files without opening it in the header file?

Suppose I have a header file foo.h that declares a structure variable

#include <stdio.h> typedef struct foo_struct foo_s; foo_s foo_function(int a); foo_s bar_function(int b); 

and the source file foo.c , which actually defines the structure

 #include "foo.h" struct foo_struct { int a; int b; }; foo_s foo_function(int a) { foo_s fs; fs.a = a; return fs; } 

Now I want to access the structure defined in foo.c in another bar.c source file, so I will try the following:

 #include "foo.h" foo_s bar_function(int b) { foo_s fb; fb.b = b; return fb; } 

... and fail with bar.c: 3: 7: error: return type is incomplete type

I understand what the problem is, but is there a workaround?

+4
source share
2 answers

You break your abstraction if you need to know the definition of struct foo_struct outside of foo.c. The whole point is to make the definition of the "private" structure a specific source file so that the other source files do not know and cannot directly manipulate members of struct foo_struct .

You need to either move bar to foo.c, or you need to put the structure definition in foo.h (making it publicly available), or you need to define an interface that allows other translation units to highlight, set, read and free elements of type foo_s without exposing details of its type, similar to how routines in stdio.h manage objects of type FILE , something like

 foo_s *create_foo(int a, int b); void set_foo(foo_s *f, char *property, int value); int get_foo(foo_s *f, char *property); void destroy_foo(foo_s **f); // sets f to NULL after deallocation. 

You would add the above interface to foo.h and implement it in foo.c; functions in other translation units (source files) will use it as:

 void blah(void) { foo_s *f = create_foo(0,0); if (f) { set_foo(f, "a", 1); set_foo(f, "b", 2); printf("a = %d, b = %d\n", get_foo(f, "a"), get_foo(f, "b"); destroy_foo(&f); assert(f == NULL); } } 

There are probably a hundred best ways to do this, but you should get this idea.

+3
source

No, there is no easy solution.

In this code

 typedef struct foo_struct foo_s; foo_s fb; fb.b = b; 

the compiler only knows that foo_s is a structure, but does not know whether b member of this structure or how large the structure is. And he definitely can't know that this is the second member to which you want to assign a value, so it just doesn't work.

The compiler can only specify what code should do if you include a structure definition.

+1
source

Source: https://habr.com/ru/post/1436613/


All Articles