Avoiding Circular Dependency in C header files - c

header1.h
-----------------
struct A{
int a;
B *b;
};
header2.h
-------------------
#include"header1.h"
typedef struct b{
int aa;
char bb;
int cc;
}B;
main.c
--------------------
#include<header2.h>
main(){
struct A *ace;
ace = malloc(sizeof(struct A));
ace->b = malloc(sizeof(B));
}
The problem: Basically, header1.h needs to use a struct defined in header2.h.
The Dilemma: Since header2.h includes header1.h, If i include header2.h in header1.h I will be introducing a circular dependency.
Some solutions: One way to solve the problem would be use a void pointer, but is there any other way? I tried forward declaring it, but it says "redifining a typedef".

So the problem you have is the pointer
B *b;
in struct A. Since this is a pointer an incomplete type is ok as long as you tell it that's what this is.
typedef struct a {
int a;
struct B *b;
} A;
or you could use the prototype form:
struct B;
typedef struct a {
int a;
B *b;
};
The compiler just wants to know what type of thing the pointer points-to just here, it doesn't actually care what it looks like in more detail until you first start trying to dereference it.

You can easily prevent your header files from being included multiple times by wrapping them like this
#ifndef FOO_H_ /* include guard */
#define FOO_H_
/* * * * * insert foo.h here * * * * */
#endif /* FOO_H_ */

I would suggest to use forward declaration in this case as struct B appears only as a pointer and dont try to access
any members of struct B. The compiler would be happy and I assume only the source code would access the members.
header1.h:
struct B;
struct A{
int a;
B *b;
}

Related

Header file typedef definition

Hi I was triying to make something like this, but I cant sort it out. The problem is one typedef needs the other one. I would really appreciate someones help!
#ifndef SHELL_DATA_H
#define SHELL_DATA_H
#include <buffer.h>
#define COMMANDS 10
#define MAX_ARGS 4
typedef struct {
void (*command)(int, char **, t_shellData *shelldData);
char *name;
char *description;
} t_command;
typedef struct {
t_command commands[COMMANDS];
t_buffer buffer;
char username[BUFFER_SIZE];
} t_shellData;
#endif
typedef struct command t_command;
typedef struct shelldata t_shellData;
struct command {
void (*command)(int, char **, t_shellData *shelldData);
char *name;
char *description;
};
struct shelldata {
t_command commands[COMMANDS];
t_buffer buffer;
char username[BUFFER_SIZE];
};
should fix it up for you. The structure tag and typedef name can be the same; I just renamed them for clarity.
C is a simple language, with an underlying principle of do not surprise people. For this reason, entities in C need to be declared or defined before they are used. As a simple example:
int f() {
int a = 7;
int b = a;
....
}
is OK, but this is not:
int f() {
int b = a;
int a = 7;
....
}
and while not exactly, languages like golang permit this -- the compiler will root around and find the definition you obviously wanted.
Typedef, in C, really just puts an entry into the symbol table; it is like a define, but less blunt, so the line:
typedef struct a A;
Serves to inform the compiler of two things: somewhere there is a structure with tag a, and I want A to be a shortform for it. There is another form of this:
struct a;
typedef struct a A;
Here, the first line tells the compiler "I want you to know about a thing called struct a"; and the second line "I want an alias to that struct a thing called A".
So, as the compiler progresses through the source, it knows that an A means a struct a, and even if it hasn't seen the definition of struct a, it has a placeholder.
But, if you attempted, before defining struct a to define another structure:
struct b {
struct a stuff;
int morestuff;
};
The compiler would complain, because it doesn't know the layout of a struct a; however this:
struct b {
struct a *stuff;
int morestuff;
};
is OK, because it knows how big a pointer is, and can defer its understanding of a struct a until it needs it.
So, Summary: declare or define data types before you attempt to use them. The C compiler requires it. A declaration is ok, unless you need the actual layout of it, in which case a definition is required.
Good Luck.

structs in different headers refer to each other

I want to have a struct that contains a pointer to another struct which in turn has a function pointer with the function argument being a pointer to the first type of struct but I'm struggling to resolve the references. The struct definitions are in different header files and must be available to other code in the full project.
In a simplified example, in main I have:
#include "a.h"
typedef struct {
int x;
int (*func)(a_t * a);
int y;
} z_t;
In a.h:
#ifndef A_H_
#define A_H_
#include "z.h"
typedef struct {
int b;
int c;
z_t * z;
} a_t;
#endif /* A_H_ */
and in z.h:
#ifndef Z_H_
#define Z_H_
#include "a.h"
typedef struct {
int x;
int (*func)(a_t * a);
int y;
} z_t;
#endif /* Z_H_ */
I end up with circular #includes and type a_t is unknown in z.h
Can anyone help?
In C, you can have a circular reference among two or more structures, or from a structure to itself. Note that the reference can be by pointer only: one structure X cannot embed an instance of another while simultaneously X embeds an instance of Y. However, X can have a pointer to Y, while Y can point to X, or embed a copy of X.
The mechanism which allows a circular reference in C is the incomplete struct type. In C you can use struct in a declaration, without defining the body of the struct, like this:
struct foo *bar; // foo has never been seen before.
The foo identifier is the "struct tag". A later re-declaration of the same struct tag in the same scope which does include a body will complete the type:
struct foo { int member; }; // foo is now complete
With this we can do:
struct list_node {
struct list_node *next, *previous; // self reference
};
struct foo {
struct bar *bar_ptr;
};
struct bar {
struct foo *foo_ptr; // mutual references
};
In your code, you haven't used a single struct tag; all your struct types are anonymous, and you are relying on typedef aliases. The above referential tricks cannot be played out using typedef names; the struct tags are essential.
Only a struct which has a tag can be declared two or more times: incomplete the first times, and then completely. The declaration of a struct with no tag is anonymous; such a declaration invents a new, unique struct type each time it appears.

What is 'forward declaration' and the difference between 'typedef struct X' and 'struct X'?

I am a beginner in C programming and I know the difference between struct type declaration and typedef struct declaration. I came across to know an answer saying that if we define a struct like:
typedef struct {
some members;
} struct_name;
Then it will be like providing an alias to an anonymous struct (as it is not having a tag name). So it can't be used for forward declaration. I don't know what the forward declaration means.
Also, I wanted to know that for the following code:
typedef struct NAME {
some members;
} struct_alias;
Is there any difference between NAME and struct_alias? Or are both equal as
struct_alias is an alias of struct NAME ?
Furthermore, can we declare a variable of type struct NAME like these:
struct_alias variable1;
and/or like:
struct NAME variable2;
or like:
NAME variable3;
struct forward declarations can be useful when you need to have looping struct declarations. Example:
struct a {
struct b * b_pointer;
int c;
};
struct b {
struct a * a_pointer;
void * d;
};
When struct a is declared it doesn't know the specs of struct b yet, but you can forward reference it.
When you typedef an anonymous struct then the compiler won't allow you to use it's name before the typedef.
This is illegal:
struct a {
b * b_pointer;
int c;
};
typedef struct {
struct a * a_pointer;
void * d;
} b;
// struct b was never declared or defined
This though is legal:
struct a {
struct b * b_pointer;
int c;
};
typedef struct b {
struct a * a_pointer;
void * d;
} b;
// struct b is defined and has an alias type called b
So is this:
typedef struct b b;
// the type b referes to a yet undefined type struct b
struct a {
b * struct_b_pointer;
int c;
};
struct b {
struct a * a_pointer;
void * d;
};
And this (only in C, illegal in C++):
typedef int b;
struct a {
struct b * struct_b_pointer;
b b_integer_type;
int c;
};
struct b {
struct a * a_pointer;
void * d;
};
// struct b and b are two different types all together. Note: this is not allowed in C++
Forward declaration is a promise to define something that you make to a compiler at the point where the definition cannot be made. The compiler can use your word to interpret other declarations that it would not be able to interpret otherwise.
A common example is a struct designed to be a node in a linked list: you need to put a pointer to a node into the struct, but the compiler would not let you do it without either a forward declaration or a tag:
// Forward declaration
struct element;
typedef struct {
int value;
// Use of the forward declaration
struct element *next;
} element; // Complete definition
and so it cant be used for forward declaration
I think that author's point was that giving your struct a tag would be equivalent to a forward declaration:
typedef struct element {
int value;
// No need for a forward declaration here
struct element *next;
} element;
Forward declaration is a declaration preceeding an actual definition, usually for the purpose of being able to reference the declared type when the definition is not available. Of course, not everything may be done with the declared-not-defined structure, but in certain context it is possible to use it. Such type is called incomplete, and there are a number of restrictions on its usage. For example:
struct X; // forward declaration
void f(struct X*) { } // usage of the declared, undefined structure
// void f(struct X) { } // ILLEGAL
// struct X x; // ILLEGAL
// int n =sizeof(struct X); // ILLEGAL
// later, or somewhere else altogether
struct X { /* ... */ };
This can be useful e.g. to break circular dependencies, or cut down the compilation time, as the definitions are usually significantly larger, and so more resources are required to parse it.
In your example, struct NAME and struct_alias are indeed equivalent.
struct_alias variable1;
struct NAME variable2;
are correct;
NAME variable3;
is not, as in C the struct keyword is required.
struct_alias and struct NAME are same ,struct_alias is an alias to struct NAME
These both are same and allowed
struct_alias variable1;
struct NAME variable1;
this is illegal
NAME variable3;
See this article on Forward declaration
As others stated before, a forward declaration in C/C++ is the declaration of something with the actual definition unavailable. Its a declaration telling the compiler "there is a data type ABC".
Lets pretend this is a header for some key/value store my_dict.h :
...
struct my_dict_t;
struct my_dict_t* create();
char* get_value(const struct my_dict_t* dict, const char* name);
char* insert(struct my_dict_t* dict, const char* name, char* value);
void destroy(struct my_dict_t* dict);
...
You dont know anything about my_dict_t, but actually, for using the store
you dont need to know:
#include "my_dict.h"
...
struct my_dict_t* dict = create();
if(0 != insert(dict, "AnEntry", strdup("AValue"))) {
...
}
...
The reason for this is: You are only using POINTERS to the data structure.
POINTERS are just numbers, and for dealing with them you dont need to know what they are pointing at.
This will only matter if you try to actually access them, like
struct my_dict_t* dict = create();
printf("%s\n", dict->value); /* Impossible if only a forward decl is available */
So, for implementing the functions, you require an actual definition of my_struct_t.
You might do this in the source file my_dict.c like so:
#include "my_dict.h"
struct my_dict_t {
char* value;
const char* name;
struct my_dict_t* next;
}
struct my_dict_t* create() {
return calloc(1, sizeof(struct my_dict_t));
}
This is handy for several situations, like
For resolving circular type dependencies, like Sergei L. explained.
For encapsulation, like in the example above.
So the question that remains is: Why cant we just omit the forward declaration at all when using the functions above? In the end, it would suffice for the compiler to know that all dict are pointers.
However, the compiler does perform type checks:
It needs to verify that you don't do something like
...
int i = 12;
char* value = get_value(&i, "MyName");
...
It does not need to know how my_dict_t looks like, but it needs to know that &i is not the type of pointer get_value() expects.

how can I use a pointer to global struct in ansi-c?

Here is the case. In the file "fileA.c" I have
typedef struct MY_STRUCT
{
int A;
int B;
int C;
}MY_STRUCT;
MY_STRUCT Data;
/* Function */
int function(MY_STRUCT *params)
{
int varA, varB, varC;
varA = params->A;
varB = params->B;
varC = params->C;
}
And I need to fill the struct elements from other routine, for instance, "fileB.c" which contains the following:
extern MY_STRUCT Data;
int function(MY_STRUCT *params);
/* Function */
void userMain(void)
{
Data.A = 1254;
Data.B = 5426;
Data.C = 1236;
function(&Data);
}
But I'm getting the error:
"[Error] fileB.c E208: syntax error - token ";" inserted before "Data"
And whe I cross probe the error the compiler take me to the declaration "extern MY_STRUCT Data;"
So my question is how do I accomplish this functionality? I mean, how do I fill the elements of the structure from another function in another file different from the file where I declared the struct?
When the compiler is compiling fileB.c, it doesn't know about the typedef that you've defined in fileA.c. So in fileB.c, MY_STRUCT is an unknown type.
You should move the typedef to a common header, and include it in fileA.c and fileB.c.
Elaborating a bit on #pb2q answer:
Create a filea.h file with (omitting the defines and stuff):
struct MY_STRUCT
{
(blah blah blah ...)
};
extern MY_STRUCT Data;
This will declare the struct and tell whoever wants to know that the variable is declared in another file. Then put in filea.c the following lines
#include "filea.h" // near the top
(...)
MY_STRUCT Data; // Somewhere meaningful
This will actually declare the variable Data. Finally, in file "fileb.c" type
#include "filea.h"
that allows you to use the variable Data.

What's the syntactically proper way to declare a C struct?

I've seen C structs declared several different ways before. Why is that and what, if anything, does each do different?
For example:
struct foo {
short a;
int b;
float c;
};
typedef struct {
short d;
int e;
float f;
} bar;
typedef struct _baz {
short a;
int b;
float c;
} baz;
int main (int argc, char const *argv[])
{
struct foo a;
bar b;
baz c;
return 0;
}
Well, the obvious difference is demonstrated in your main:
struct foo a;
bar b;
baz c;
The first declaration is of an un-typedefed struct and needs the struct keyword to use. The second is of a typedefed anonymous struct, and so we use the typedef name. The third combines both the first and the second: your example uses baz (which is conveniently short) but could just as easily use struct _baz to the same effect.
Update: larsmans' answer mentions a more common case where you have to use at least struct x { } to make a linked list. The second case wouldn't be possible here (unless you abandon sanity and use a void * instead) because the struct is anonymous, and the typedef doesn't happen until the struct is defined, giving you no way to make a (type-safe) pointer to the struct type itself. The first version works fine for this use, but the third is generally preferred in my experience. Give him some rep for that.
A more subtle difference is in namespace placement. In C, struct tags are placed in a separate namespace from other names, but typedef names aren't. So the following is legal:
struct test {
// contents
};
struct test *test() {
// contents
}
But the following is not, because it would be ambiguous what the name test is:
typedef struct {
// contents
} test;
test *test() {
// contents
}
typedef makes the name shorter (always a plus), but it puts it in the same namespace as your variables and functions. Usually this isn't an issue, but it is a subtle difference beyond the simple shortening.
It's largely a matter of personal preference. I like to give new types a name starting with a capital letter and omit the struct, so I usually write typedef struct { ... } Foo. That means I cannot then write struct Foo.
The exception is when a struct contains a pointer to its own type, e.g.
typedef struct Node {
// ...
struct Node *next;
} Node;
In this case you need to also declare the struct Node type, since the typedef is not in scope within the struct definition. Note that both names may be the same (I'm not sure where the underscore convention originated, but I guess older C compilers couldn't handle typedef struct X X;).
All your uses are syntactically correct. I prefer the following usage
/* forward declare all structs and typedefs */
typedef struct foo foo;
.
.
/* declare the struct itself */
struct foo {
short a;
int b;
foo* next;
};
Observe that this easily allows to use the typedef already inside the declaration of the struct itself, and that even for struct that reference each other mutually.
The confusion comes about because some of the declarations are in fact declaring up to three C constructs. You need to keep in mind the difference between:
A typedef declaration,
A struct definition, and
A struct declaration.
They are all very different C constructs. They all do different things; but you can combine them into the one compound construct, if you want to.
Let's look at each declaration in turn.
struct foo {
short a;
int b;
float c;
};
Here we are using the most basic struct definition syntax. We are defining a C type and give it the name foo in the tag namespace. It can later be used to declare variables of that type using the following syntax:
struct foo myFoo; // Declare a struct variable of type foo.
This next declaration gives the type another name (alias) in the global namespace. Let's break it down into its components using the previous basic declaration.
typedef foo bar; // Declare bar as a variable type, the alias of foo.
bar myBar; // No need for the "struct" keyword
Now just replace "foo" with the the struct's definition and voila!
typedef struct {
short d;
int e;
float f;
} bar;
typedef struct _baz {
short a;
int b;
float c;
} baz;
The above syntax is equivalent to the following sequence of declarations.
struct _baz {
short a;
int b;
float c;
}
typedef _baz baz; // Declare baz as an alias for _baz.
baz myBaz; // Is the same as: struct _baz myBaz;

Resources