I have this situation:
A.h and B.h
In A.h:
typedef struct TypeA TypeA_t;
struct TypeA {
...
TypeA_t *a;
void (*doSomething)(TypeB_t *);
};
In B.h:
typedef struct TypeB TypeB_t;
struct TypeB {
...
TypeB_t *b;
TypeA_t something;
};
What is the correct way to include header files in each file?
If I include A.h in B.h and B.h in A.h I get:
error: unknown type name 'TypeB_t' in A.h
and
error: unknown type name 'TypeA_t' in B.h
I found a similar question here but it doesn't work in my case.
The way you've defined your code, TypeA can live with a forward reference to TypeB, but TypeB needs the full declaration of TypeA to compile.
In other words, you need to do two things. First forward define TypeB in a.h before your class definition (because pointers can work with partial definitions):
//a.h
typedef struct TypeB TypeB_t;
typedef struct TypeA TypeA_t;
struct TypeA {
...
TypeA_t *a;
void (*doSomething)(TypeB_t*);
};
And then include a.h from b.h to get the declaration for your class (because you use the full TypeA class as a field type):
// b.h
#include "a.h"
typedef struct TypeB TypeB_t;
struct TypeB {
...
TypeB_t *b;
TypeA_t something;
};
The typedefs can be moved to other header files, and use header guard macros to prevent multiple definitions:
At.h
#ifndef AT_H_INCLUDED_
#define AT_H_INCLUDED_
typedef struct TypeA TypeA_t;
#endif
Bt.h
#ifndef BT_H_INCLUDED_
#define BT_H_INCLUDED_
typedef struct TypeB TypeB_t;
#endif
A.h
#ifndef A_H_INCLUDED_
#define A_H_INCLUDED_
#include "At.h"
#include "Bt.h"
struct TypeA {
TypeA_t *a;
void (*doSomething)(TypeB_t *);
};
#endif
B.h
#ifndef B_H_INCLUDED_
#define B_H_INCLUDED_
#include "Bt.h"
#include "A.h"
struct TypeB {
TypeB_t *b;
TypeA_t something;
};
#endif
.c files shouldn't need to include "At.h" or "Bt.h". The inclusion of "At.h" and "Bt.h" can be policy restricted to be included only by the main header files. Including "A.h" will fully define TypeA_t. Including "B.h" will fully define TypeB_t (and will also fully define TypeA_t). They can be included in any order.
Related
I'm trying to define a structure as a typedef in a header file and use it in many sources. I found a similar answer in here but I'm not sure if a typedef can be defined as extern. Also msg_encoded should have a default value.
// lib.h
#ifndef lib_h
#define lib_h
struct msg_encoded_s
{
uint8_t msg[10];
int length;
} msg_encoded_default = {{0}, 0};
typedef struct msg_encoded_s msg_encoded;
#endif
// lib.c
#include "lib.h"
msg_encoded some_var;
// main.c
# include "lib.h"
int main(){
msg_encoded some_other_var;
}
main.o:(.bss.msg_encoded_default+0x0): multiple definition of
`msg_encoded_default'
A "declaration" like
struct msg_encoded_s {
...
} msg_encoded_default;
is actually both (1) a definition of a struct-type named msg_encoded_s and (2) the definition of a variable of this type named `msg_encoded_default.
Hence, if you include this header file in separate translation units, then you will redefine a variable named msg_encoded_default, which is not allowed.
To overcome this, write a header like...
typedef struct msg_encoded_s
{
uint8_t msg[10];
int length;
} msg_encoded;
extern msg_encoded msg_encoded_default;
An in exactly one translation unit write:
#include "myheader.h"
msg_encoded msg_encoded_default = {{0}, 0};
In all other translation units just write...
#include "myheader.h"
...
int test = msg_encoded_default.length; // or something like this
I have two header files
A.h
struct A { ... };
function declarations which use A
B.h
function declarations which use the struct A here, and have functions which also use A.
However, I want to call "A" B here. How can I do this? I want all the
functions in here use
struct B, which I want to be exactly the same as struct A since
An example of what I "want" to do, but uses defines and is probably the wrong way of doing things: (Note, it works perfectly how I want it to, but I don't think I should be using defines for this purpose, there is probably a better way of doing things)
A.h
#ifndef A_H
#define A_H
struct A {int x;};
void A_DoSomething(struct A* a);
#endif
B.h
#ifndef B_H
#define B_H
#include "A.h"
#define B A
void B_DoSomething(struct* B b) { A_DoSomething(b); }
#endif
So is there a way to do what I want without using define? I want to do this so I can reuse code. I.e., A is a linked list, B is a stack. I can completely define my stack data structure from a linked list.
EDIT: So basically B and A are equivalent, but for my B.h/B.c file, and any files using B.h, I just want to call the structure "B" and not "A"
I would use typedef and use 3 h-files to separate the common data structure from A and B. Something like:
MyNode.h:
#ifndef MyNode_H
#define MyNode_H
typedef struct Node
{
void *data;
struct Node *next;
} Node;
#endif
A.h:
#ifndef A_H
#define A_H
#include "MyNode.h"
typedef Node A;
/* Declare functions for implementing a linked list using type A */
#endif
B.h:
#ifndef B_H
#define B_H
#include "MyNode.h"
typedef Node B;
/* Declare functions for implementing a stack using type B */
#endif
Main.c:
#include <stdio.h>
#include "A.h"
#include "B.h"
int main(void) {
/* Here A and B can be used as types, example: */
A list = {NULL, NULL};
B stack = {NULL, NULL};
return 0;
}
I am encountering the following problem in C:
I declare a typedef for a struct in a headerfile ("mep.h")
#ifndef MEP_H
#define MEP_H
typedef struct Mep_tag Mep;
<other stuff declared here>
#endif
I use another headerfile ("mep_types.h") that includes "mep.h", defines the struct "Mep_tag" and uses the "Mep" type name:
#ifndef MEP_TYPES_H
#define MEP_TYPES_H
#include "mep.h"
#include "file1.h"
struct Mep_MsgElement_tag
{
const Mep * MsgCh;
};
struct Mep_tag
{
<stuff in here>
};
#endif
For some reason when this compiles, I get the following error:
"mep_types.h: error: unknown type name "'Mep'".
However, if in the "mep.h" I place the typedef outside the ifndef guard like this...
typedef struct Mep_tag Mep;
#ifndef MEP_H
#define MEP_H
<other stuff declared here>
#endif
... the "Mep" type name is visible in "mem_types.h".
Might someone know how this could happen?
I have two .h files and a .c file as below
a.h
typedef struct mode_info_t_ mode_info_t;
struct common {
int create;
mode_info_t *mode_info;
};
b.h
typedef struct mode_info_t_ {
int primary;
int secondary;
} mode_info_t;
main.c
#include "a.h"
#include "b.h"
-----
When .c is compiled it throws below error -
b.h:17: error: redefinition of typedef 'mode_info_t'
a.h:50: error: previous declaration of 'mode_info_t' was here
What is wrong here experts?
Change b.h to this:
struct mode_info_t_ {
int primary;
int secondary;
};
If you need the typedef in b.h, have b.h include a.h. If you don't want to have b.h include a.h but still need the typedef in both, then take the typedef out of a.h and put it in c.h, and have both a.h and b.h include c.h.
I've actually done this before where I put all my forward declarations in a separate header, just to avoid the need for various headers including each other when it wasn't totally appropriate.
You have your b.h
typedef struct mode_info_t_ {
int primary;
int secondary;
}mode_info_t;
Then a.h
struct common {
int create;
mode_info_t *mode_info;
};
In your main.c just include b.h
#include "b.h"
#include "a.h"
int main()
{
}
When I compile the snippet you have given, I didn't get any errors and warnings. Can you show us your full code? It is possible to declare a structure and after that you can define it.
typedef struct Node Node;
struct Node {
int data;
Node *nextptr;
};
Here you are doing the same thing. So it not an error. You may have mishandled it somewhere.
I've got two structures in two different header files, let's say:
header1.h:
#ifndef HEADER1_H
#define HEADER1_H
#include "header2.h"
typedef struct
{
Struct2 s;
} Struct1;
#endif
header2.h:
#ifndef HEADER2_H
#define HEADER2_H
#include "header1.h"
typedef struct
{
Struct1* s;
} Struct2;
#endif
As you can see i declare Struct2 in Struct1 and pointer to Struct1 in Struct2. Obviously when i try to compile this it gives me an error: unknown type name ‘Struct1’ or 'Struct2'. Is there any way to do this or i must change my conception?
If you really want to do this, you can, you just need to use partial declarations before really declaring each structure:
header1.h
#ifndef _HEADER1_H
#define _HEADER1_H
#include "header2.h"
struct struct1
{
struct struct2 s2;
};
#endif
header2.h
#ifndef _HEADER2_H
#define _HEADER2_H
struct struct1;
struct struct2
{
struct struct1 *s1;
};
#endif