I made a template list with help of macroses. And I have an error, when I use it in more then one time in the code. There is a link error LNC2005 in MS VS.
I think, it happens, because bodies of functions are in the header, is there another way to keep them?
#define GENERIC_LIST_POSTFIX i
#define GENERIC_LIST_TYPE int
#define GENERIC_LIST_NAME list
#include "generic_list.h"
#undef GENERIC_LIST_POSTFIX
#undef GENERIC_LIST_TYPE
#undef GENERIC_LIST_NAME
If I can't change a language, what can You advice to me?
Thanks.
There is my code
#ifndef _GENERIC_LIST_H
#define _GENERIC_LIST_H
#define _CAT(x,y) x##y
#define CAT(x,y) _CAT(x,y)
#if !defined GENERIC_LIST_POSTFIX
# error("GENERIC_LIST_POSTFIX")
#endif
#if !defined GENERIC_LIST_TYPE
# error("GENERIC_LIST_TYPE")
#endif
#if !defined GENERIC_LIST_NAME
# error("GENERIC_LIST_NAME")
#endif
//-------------------------------------------------------------------------------
typedef struct CAT(CAT(_list_,GENERIC_LIST_POSTFIX),_node) CAT(GENERIC_LIST_NAME,_node);
struct CAT(CAT(_list_,GENERIC_LIST_POSTFIX),_node)
{ GENERIC_LIST_TYPE value;
struct CAT(CAT(_list_,GENERIC_LIST_POSTFIX),_node) *prev;
struct CAT(CAT(_list_,GENERIC_LIST_POSTFIX),_node) *next;
};
//typedef struct CAT(_list_,GENERIC_LIST_POSTFIX) GENERIC_LIST_NAME;
struct CAT(_list_,GENERIC_LIST_POSTFIX)
{ unsigned int len; // number of elements
struct CAT(CAT(_list_,GENERIC_LIST_POSTFIX),_node) *first;
struct CAT(CAT(_list_,GENERIC_LIST_POSTFIX),_node) *last;
};
//-------------------------------------------------------------------------------
void CAT(CAT(list_,GENERIC_LIST_POSTFIX),_create )
(struct CAT(_list_,GENERIC_LIST_POSTFIX) *List);
{ List->len = 0; List->first = NULL; List->last = NULL; }
void CAT(CAT(list_,GENERIC_LIST_POSTFIX),_copy )
(struct CAT(_list_,GENERIC_LIST_POSTFIX) *scr, struct CAT(_list_,GENERIC_LIST_POSTFIX) *dest);
{ // ... }
// ... there are more code
#endif
All works, but there is another problem.
I can use this .h file only one time in a one .c file.
If I define GENERIC_LIST_TYPE firstly as int, than as int*, for example.
#define GENERIC_LIST_POSTFIX i
#define GENERIC_LIST_TYPE int
#define GENERIC_LIST_NAME list_i
#include "generic_list.h"
#undef GENERIC_LIST_POSTFIX
#undef GENERIC_LIST_TYPE
#undef GENERIC_LIST_NAME
#define GENERIC_LIST_POSTFIX pi
#define GENERIC_LIST_TYPE int*
#define GENERIC_LIST_NAME list_pi
#include "generic_list.h"
#undef GENERIC_LIST_POSTFIX
#undef GENERIC_LIST_TYPE
#undef GENERIC_LIST_NAME
I don't get 2 lists with list_i and list_pi names.
The second "list_pi" is "undeclared identifier".
Is there a solution for this?
Thank you twice.
If I read your question right, you have a header like this:
void doSomething()
{
printf("doing something");
}
Which causes link errors when you include the file multiple times.
However, if you make the function static:
static void doSomething()
{
printf("doing something");
}
The method will not be put to the linker, so you won't have to worry about linker errors.
Your other option is to put a method declaration in your header, and an implementation in a .c file elsewhere in your project.
Related
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;
}
Basically, I need to have typedef in one header file and use it on another header.
myType.h:
#ifndef deque_H
#define deque_H
#include "deque.h"
typedef int intDef;
#endif
deque.h:
#ifndef deque_H
#define deque_H
#include "myType.h"
typedef struct dequeNode *link;
struct dequeNode{
intDef data;
link next;
//count
};
#endif
I want to use intDef in deque.h, but I get project error \deque.h|6|error: unknown type name 'intDef'|
Does anybody have a clue what's wrong? myType.h is in the same project.
You prevent your myType.h from ever being executed, since you use the same flag as in the other file. You need to choose any other symbol and check if it's defined:
#ifndef myType_H
#define myType_H
typedef int intDef;
#endif
In my C project, I have a header file with a declaration of a struct (with an alias) and a header file with functions that accept that struct as an argument (using the alias). I am receiving the error expected ')' before '*' token on the function. From researching, I think this indicates that the alias is not visible in the function's namespace. I have a fairly convoluted include web that I believe may be causing this. Here is a simplified example.
Struct declaration header:
#ifndef STRUCTHEADER_H_
#define STRUCTHEADER_H_
#endif /* STRUCTHEADER_H_ */
#ifndef STRUCTFUNCTIONS_H_
#include "structFunctions.h"
#endif
struct myStruct{
};
typedef struct myStruct mys;
Struct function header:
#ifndef STRUCTFUNCTIONS_H_
#define STRUCTFUNCTIONS_H_
#endif /* STRUCTFUNCTIONS_H_ */
#ifndef STRUCTHEADER_H_
#include "structHeader.h"
#endif
void func(mys* s);
main.c:
#ifndef STRUCTHEADER_H_
#include "structHeader.h"
#endif
int main(int argc, char* argv[]){
return 0;
}
However, when I change main.c to this:
#ifndef STRUCTFUNCTIONS_H_
#include "structFunctions.h"
#endif
int main(int argc, char* argv[]){
return 0;
}
the error goes away. Am I using include wrong?
You need to change structHeader.h so that it declares the structure before it includes structFunctions.h, because the function definition needs to refer to the alias. In C, you can only refer to names that have been previously declared.
#ifndef STRUCTHEADER_H_
#define STRUCTHEADER_H_
#endif /* STRUCTHEADER_H_ */
struct myStruct{
};
typedef struct myStruct mys;
#ifndef STRUCTFUNCTIONS_H_
#include "structFunctions.h"
#endif
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
I have a typedef struct declared in one my headers. Its associated C file can find the typedef, but other headers have trouble reading it.
// In projectiles.h I have
#ifndef PROJECTILES_H_
#define PROJECTILES_H_
struct TheProjectile { };
typedef struct TheProjectile Projectile;
#endif /* PROJECTILES_H_ */
In physics.h I want to use Projectile
#ifndef PHYSICS_H_
#define PHYSICS_H_
#include "projectiles.h"
struct TheProjectile;
void set_Current_Angle(Projectile* PI);
#endif /* PHYSICS_H_ */
However, in Eclipse I keep getting "expecting ) before PI" error. Without typedef it does work fine. What am I doing wrong?