C recursive header file inclusion problem? - c

Suppose you have to related structures defined in 2 header files like below:
a.h contents:
#include b.h
typedef struct A
{
B *b;
} A;
b.h contents:
#include a.h
typedef struct B
{
A *a;
} B;
In such this case, this recursive inclusion is a problem, but 2 structures must point to other structure, how to accomplish this?

Don't #include a.h and b.h, just forward-declare A and B.
a.h:
struct B; //forward declaration
typedef struct A
{
struct B * b;
} A;
b.h:
struct A; //forward declaration
typedef struct B
{
struct A * a;
} B;
You might want to think about how tightly coupled the classes are. If they're very tightly coupled, then maybe they belong in the same header.
Note: you'll need to #include both a.h and b.h in the .c files to do things like a->b->a.

Google C/C++ guidelines suggests:
Don't use an #include when a forward declaration would suffice
That'd mean:
a.h contents:
typedef struct B B;
typedef struct A
{
B *b;
} A;
b.h contents:
typedef struct A A;
typedef struct B
{
A *a;
} B;
If you prefer something a bit safer (but longer to compile) you can do this:
a.h contents:
#pragma once
typedef struct A A;
#include "B.h"
typedef struct A
{
B *b;
} A;
b.h contents:
#pragma once
typedef struct B B;
#include "A.h"
typedef struct B
{
A *a;
} B;

You pre-define the struct only, in that way you can still declare a pointer:
In a.h:
typedef struct B_ B;
typedef struct A_
{
B *b;
} A;
Note how I use separate names for the typedef and struct tags, to make it a bit clearer.

This will cut it in C:
typedef struct B B;
typedef struct A A;
struct A { B *b; };
struct B { A *a; };
You can rearrange B and A as desired.

Related

Is there a way to add new members to structure in C? [duplicate]

typedef struct foo_s {
int a;
} foo;
typedef struct bar_s {
foo;
int b;
} bar;
Essentially I want to do:
bar b;
b.a;
I know that i could do b.foo_name.a if I had named the foo struct in bar, but Id prefer not to.
Any way to do this?
This question has gotten a variety of different answers, so let me explain the need. The reason I want to do this is because I have a library which I need to adapt to my situation, meaning that I cant modify the original struct decleration. Furthermore, all I need to do is add 1 item to the beginning of the struct (why the beginning? because I have an 'object' struct which heads all the structs in the project). I could simply embed the struct like you mention but its REALLY annoying as all references will need to be typed 'variable->image.location' that 'image.' typed a billion types is really annoying.
Evidently this feature has been added to C11, but alas I don't have access to a C compiler of recent vintage (>= GCC 4.6.2).
typedef struct foo {
int a;
} foo;
typedef struct bar {
struct foo;
int b;
} bar;
int main() {
bar b;
b.a = 42;
b.b = 99;
return 0;
}
You can, using pointers, because a pointer to a structure object is guaranteed to point its first member. See e.g. this article.
#include <stdlib.h>
#include <stdio.h>
typedef struct foo_s {
int a;
} foo;
typedef struct bar_s {
foo super;
int b;
} bar;
int fooGetA(foo *x) {
return x->a;
}
void fooSetA(foo *x, int a) {
x->a = a;
}
int main() {
bar* derived = (bar*) calloc(1, sizeof(bar));
fooSetA((foo*) derived, 5);
derived->b = 3;
printf("result: %d\n", fooGetA((foo*) derived));
return 0;
}
Not possible in C the way you did. But you can mimic inheritance having a foo member variable in bar.
typedef struct bar_s {
foo obj;
int b;
} bar;
bar b;
b.obj.a = 10;
If you ment
typedef struct foo_s {
int a;
} foo;
typedef struct bar_s {
foo my_foo;
int b;
} bar;
so you can do:
bar b; b.my_foo.a = 3;
Otherwise, There's no way of doing it in C since the sizeof(bar_s) is detriment on compile time. It's not a good practice but you can save a void * ptr; pointer within bar_s, and another enum which describes the ptr type, and cast by the type.
i.e:
typedef enum internalType{
INTERNAL_TYPE_FOO = 0,
}internalType_t;
typedef struct bar_s {
internalType_t ptrType;
void* ptr;
int b;
} bar;
and then:
bar b; foo f;
b.ptrType = INTERNAL_TYPE_FOO;
b.ptr = &f;
and some where else in the code:
if (b.ptrType == INTERNAL_TYPE_FOO) {
foo* myFooPtr = (foo *)b.ptr;
}
It can be easily done via preprocessor:
Create a file named base_foo.h:
int foo;
Then simply include it:
typedef struct foo_s {
#include "base_foo.h"
} foo;
typedef struct bar_s {
#include "base_foo.h"
int b;
} bar;
There is a confusion between anonymous structures and unions with nameless field. The nameless field is a Microsoft Extension.
struct known {
struct /* anonymous */ {
int anonymous;
};
int known;
};
An anonymous struct or union is a struct or union without any tag name that is embedded within another struct or union. It does not need to have any field names either.
A nameless field is a Microsoft Extension that allows limited inheritance in C.
struct A {
int a;
};
struct B {
struct A: // nameless field
int b;
};
Anonymous struct or union are not Nameless Fields, and Nameless Fields are not Anonymous, at least the way C11 standard defines it.
You can try using inheritance:
struct foo_s
{
int a;
};
struct bar_s: foo_a
{
int b;
};
Works in C++, not sure if it works in C.
This is the simplest way without the c flags
#include <stdio.h>
#define foo_s struct { int a; }
typedef foo_s foo;
typedef struct bar_s {
foo_s; // extends foo_s
int b;
} bar;
int main(void)
{
bar b = {
.a = 1,
.b = 2,
};
foo *f = (foo *)&b;
printf("a: %d\n", f->a);
return 0;
}
$ gcc inherit.c
$ ./a.out
a: 1

How to handle circular dependencies in typedef'd structures

I have two modules, a and b.
a.h:
#ifndef A_H_
#define A_H_
#include "b.h"
typedef struct {
b_t *b;
...
} a_t;
#endif // A_H_
b.h:
#ifndef B_H_
#define B_H_
#include "a.h"
typedef struct {
a_t *a;
...
} b_t;
#endif // B_H_
How do I alter this so that it will compile? (I want to keep two separate compilation units.)
edit: I forgot to make the structure members pointers.
Use forward declarations:
a.h:
struct b_t;
typedef struct a_t {
struct b_t *b;
} a_t;
b.h:
struct a_t;
typedef struct b_t {
struct a_t *a;
} b_t;
[This answer only applies to the original question, where pointers were not used as the struct members].
that's impossible. it's naturally not possible to have such structure.
let's say:
struct a {
struct b b;
int i;
};
struct b {
struct a a;
int i;
};
what do you expect from sizeof(struct a)? this struct will explode, it's impossible to compile.
however, it can be compiled if you have them turn to pointers:
struct a;
struct b {
struct a *ap;
};
struct a {
struct b *bp;
};
this code indeed compiles: http://ideone.com/GKdUD9.
Exactly this isn't possible. You can't have a struct be its own member, not even transitively. This is however possible when you use a pointer. Use a structure declaration:
typedef struct a_struct *a_t;
typdef struct {
a_t a;
} *b_t;
typedef struct a_struct {
b_t b;
} a_t;
[This answer only applies to the original question, where pointers were not used as the struct members].
You can't.
Essentially you have
typedef struct {
b_t b;
} a_t;
typedef struct {
a_t a;
} b_t;
and no forward declaration can help you. You have an impossible structure here: the sizeof would be infinite.

Interdependent headers not compiling

I have 2 headers that depend on each other, both are guarded. But compilation fails as if the type weren't declared:
error: unknown type name Type_1
the first header:
#ifndef HEADER1_H
#define HEADER1_H
#include "header2.h"
typedef struct {
int a;
char *b;
} Type_1;
void function(Type_3 *type_3);
#endif
second header
#ifndef HEADER2_H
#define HEADER2_H
#include "header1.h"
typedef struct {
int a;
char *b;
Type_1 *c;
} Type_2;
typedef struct {
int a;
char *b;
Type_2 *c;
} Type_3;
#endif
How to solve it without resorting to hacks?
You must forward declare at least one struct. I'd personally put them all in one header, since there's not that much there.
First header:
#ifndef HEADER1_H
#define HEADER1_H
#include "header2.h"
typedef struct Type_1 {
int a;
char *b;
} Type_1;
void function(Type_3 *type_3);
#endif
The second header:
#ifndef HEADER2_H
#define HEADER2_H
struct Type_1;
typedef struct {
int a;
char *b;
struct Type_1 *c;
} Type_2;
typedef struct {
int a;
char *b;
Type_2 *c;
} Type_3;
#endif
Move all your types definitions to one files and functions declarations to another one.
header1.h
#ifndef HEADER1_H
#define HEADER1_H
typedef struct {
int a;
char *b;
} Type_1;
typedef struct {
int a;
char *b;
Type_1 *c;
} Type_2;
typedef struct {
int a;
char *b;
Type_2 *c;
} Type_3;
#endif
header2.h
#ifndef HEADER2_H
#define HEADER2_H
#include "header1.h"
void function(Type_3 *type_3);
#endif
As you use your structures as imcomplete data types, forward declaration is enough:
#ifndef HEADER2_H
#define HEADER2_H
struct Type1;
typedef struct Type1 Type1;
typedef struct {
int a;
char *b;
Type_1 *c;
} Type_2;
typedef struct {
int a;
char *b;
Type_2 *c;
} Type_3;
#endif
Apply same technique to second file. Though, in source code, you need to include header if you don't use your structures as incomplete types. More information about incomplete data types is available in this MSDN article

Two way struct pointer link, C

Is it possible to form a two way link between structs? I tried to achieve it like this:
typedef struct
{
int foo;
b *b;
} a;
typedef struct
{
int bar;
a *a;
} b;
But the struct a does not know what b is because it's declared afterwards.
Try this,
typedef struct a a;
typedef struct b b;
struct a
{
int foo;
b *b;
} ;
struct b
{
int bar;
a *a;
} ;
When you need to reference other structs that may have not been defined up until then, make your declaration like this and it should work:
typedef struct
{
int foo;
struct b *b;
} a;
typedef struct
{
int bar;
struct a *a;
} b;

Can I 'extend' a struct in C?

typedef struct foo_s {
int a;
} foo;
typedef struct bar_s {
foo;
int b;
} bar;
Essentially I want to do:
bar b;
b.a;
I know that i could do b.foo_name.a if I had named the foo struct in bar, but Id prefer not to.
Any way to do this?
This question has gotten a variety of different answers, so let me explain the need. The reason I want to do this is because I have a library which I need to adapt to my situation, meaning that I cant modify the original struct decleration. Furthermore, all I need to do is add 1 item to the beginning of the struct (why the beginning? because I have an 'object' struct which heads all the structs in the project). I could simply embed the struct like you mention but its REALLY annoying as all references will need to be typed 'variable->image.location' that 'image.' typed a billion types is really annoying.
Evidently this feature has been added to C11, but alas I don't have access to a C compiler of recent vintage (>= GCC 4.6.2).
typedef struct foo {
int a;
} foo;
typedef struct bar {
struct foo;
int b;
} bar;
int main() {
bar b;
b.a = 42;
b.b = 99;
return 0;
}
You can, using pointers, because a pointer to a structure object is guaranteed to point its first member. See e.g. this article.
#include <stdlib.h>
#include <stdio.h>
typedef struct foo_s {
int a;
} foo;
typedef struct bar_s {
foo super;
int b;
} bar;
int fooGetA(foo *x) {
return x->a;
}
void fooSetA(foo *x, int a) {
x->a = a;
}
int main() {
bar* derived = (bar*) calloc(1, sizeof(bar));
fooSetA((foo*) derived, 5);
derived->b = 3;
printf("result: %d\n", fooGetA((foo*) derived));
return 0;
}
Not possible in C the way you did. But you can mimic inheritance having a foo member variable in bar.
typedef struct bar_s {
foo obj;
int b;
} bar;
bar b;
b.obj.a = 10;
If you ment
typedef struct foo_s {
int a;
} foo;
typedef struct bar_s {
foo my_foo;
int b;
} bar;
so you can do:
bar b; b.my_foo.a = 3;
Otherwise, There's no way of doing it in C since the sizeof(bar_s) is detriment on compile time. It's not a good practice but you can save a void * ptr; pointer within bar_s, and another enum which describes the ptr type, and cast by the type.
i.e:
typedef enum internalType{
INTERNAL_TYPE_FOO = 0,
}internalType_t;
typedef struct bar_s {
internalType_t ptrType;
void* ptr;
int b;
} bar;
and then:
bar b; foo f;
b.ptrType = INTERNAL_TYPE_FOO;
b.ptr = &f;
and some where else in the code:
if (b.ptrType == INTERNAL_TYPE_FOO) {
foo* myFooPtr = (foo *)b.ptr;
}
It can be easily done via preprocessor:
Create a file named base_foo.h:
int foo;
Then simply include it:
typedef struct foo_s {
#include "base_foo.h"
} foo;
typedef struct bar_s {
#include "base_foo.h"
int b;
} bar;
There is a confusion between anonymous structures and unions with nameless field. The nameless field is a Microsoft Extension.
struct known {
struct /* anonymous */ {
int anonymous;
};
int known;
};
An anonymous struct or union is a struct or union without any tag name that is embedded within another struct or union. It does not need to have any field names either.
A nameless field is a Microsoft Extension that allows limited inheritance in C.
struct A {
int a;
};
struct B {
struct A: // nameless field
int b;
};
Anonymous struct or union are not Nameless Fields, and Nameless Fields are not Anonymous, at least the way C11 standard defines it.
You can try using inheritance:
struct foo_s
{
int a;
};
struct bar_s: foo_a
{
int b;
};
Works in C++, not sure if it works in C.
This is the simplest way without the c flags
#include <stdio.h>
#define foo_s struct { int a; }
typedef foo_s foo;
typedef struct bar_s {
foo_s; // extends foo_s
int b;
} bar;
int main(void)
{
bar b = {
.a = 1,
.b = 2,
};
foo *f = (foo *)&b;
printf("a: %d\n", f->a);
return 0;
}
$ gcc inherit.c
$ ./a.out
a: 1

Resources