I am trying to have a dictionary_object structure named dict_obj available in two separate .c files. This is while trying to write a pthread TCP server for a class. I have not worked much with C before and am having a difficult time getting this figured out. I'm not sure if I'm declaring this as an external structure correctly as netbeans is throwing off errors on clean and build saying invalid use of undefined type.
In db_functions.c I have:
//------------------------------------------------------------------------------
// Server Function & Variable Initialization
//------------------------------------------------------------------------------
struct dictionary_object dict_obj;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Server Function Codes:
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Database Initialization
//------------------------------------------------------------------------------
int db_initialization()
{
dict_obj.word_count = 0;
return 1;
In db_operations.c I have:
struct dictionary_object
{
char dictionary[DICTIONARY_SIZE][WORD_LENGTH];
int word_count;
pthread_mutex_t dict_mutex;
};
extern struct dictionary_object dict_obj;
Hopefully this gives you guys enough idea of what I'm trying to accomplish without having to overwhelm you with too much code. Thanks in advance! Let me know if you need to see more of the code.
You need to define the structure contents and layout once in an include file. Also define the "extern" definitions for all functions and statics for the code there. In any file wanting to use those structs or definitions, include the header file (something like db_struct.h).
db_struct.h:
struct dictionary_obhect {
char dictionary ...
}
extern struct dictionary_object dict_obj;
extern int db_initialization();
db_struct.c:
#include "db_struct.h"
struct dictionary_object dict_obj;
int db_initiatilization() {
dict_obc.word_count = 0;
}
Note this is all pretty old-style C code. Modern C++ etc. have other means of doing similar things.
I'll go out on a limb and guess that your problem is that the C compiler complains that it doesn't know how to allocate memory for a struct dictionary_object when it compiles db_functions.c. Its confusion is understandable because the file you're asking it to compile doesn't tell it what struct dictionary_object is at all.
You should move the definition of the struct to a header file that both of your .c files include.
Related
I'm fairly new to the C language, but have acquired some experience. Now I'm on my way creating larger projects with (more or less) complex data structures (e.g. Map (I will use Maps as an example thoughout)). Since I want my data structure code to be reusable for future projects, I like them being rather generic and in separate files.
Since C doesn't use/have Generics (like Java) oder Templates (like C++) or any similar concept I thought about using a globally defined data type like
typedef union {
int integer;
char * str;
// etc.
} data_t;
and put that in a main.h which will be included into all other (header) files (possible using guards). This works fairly well for me, but …
is there a way to integrate data structures into my data_t (which include main.h to use data_t) ?
The simple-but-obviously-not-working (due to circular includes) solution is to #include "map.h" in main.h while also including main.h in map.h; as mentioned, this doesn't work for obvious reasons.
Basically I want a Map that can hold other Maps, all while using only one data_t and one Map-implementation. Keeping track of which "layer" I am on will be done in the surrounding program (or maybe I can add some info in the data_t about its type, this is not the focus here).
I know that this will be possible when just using a void *; but I don't want unnecessary references for primitive datatypes like int if I don't have to.
Is there any clean way to do such behavior ?
Thank you !
(if any actual code is needed, tell me)
actual code
main.h which I want to contain general declarations like my data_t:
#ifndef _MAIN_H_
#define _MAIN_H_
#include "map.h"
typedef union {
int integer;
char * str;
map_t map;
} data_t;
#endif
map.h:
#ifndef _MAP_H_
#define _MAP_H_
#include "main.h"
typedef char * key_t;
typedef struct {
int (*hash_f)(key_t);
int size;
data_t * data;
} map_t;
int map_init(map_t * map, int (*hash_f)(key_t key));
int map_put(map_t map, key_t key, data_t data);
int map_get(map_t map, key_t key);
#endif
compiling with make:
% make
gcc -Wall -Wextra -Wpedantic -g -c main.c -o build/main.o
In file included from main.c:1:
./main.h:8:5: error: unknown type name 'map_t'
map_t map;
^
1 error generated.
make: *** [build/main.o] Error 1
Get your declarations and typedefinitions working within one source code file.
When that compiles, think what to put in a header. That way you make sure that at first you see what the compiler sees for one (each) code file your header gets included into.
If you cannot get it to work within one non-including code file, then you have a problem that cannot be solved with headers and guards.
If however you can do it, then just look at the single file and think "Now what do I want to also use in the next code file?" and put that into a header. (Make of course sure to only move declarations, typedefs, macro-defs into a header. Code, variable definitions do not go into headers.)
Circular dependencies cannot be solved by guards, only redefinitions due to (indirect) multiple inclusion.
api.h
The following API is assumed to be distributed as a shared library.
#include "apiInternal.h"
internalStruct* API_init();
extern void API_set_member1(internalStruct* apiStruct, int value);
extern void API_set_member2(internalStruct* apiStruct, int value);
apiInternal.h
typedef struct internalStruct {
int member1;
int member2;
} internalStruct;
sample.c
The program sample.c uses api.h and links with the shared library to use the API.
#include "api.h"
int main()
{
internalStruct *myVar = API_init();
API_set_member1(myVar, 5);
API_set_member2(myVar, 6);
}
The dilemma here is,
Should the api.h that the API implementation uses be different than
the api.h distributed to the users of the API? If so, how can I do
this without including apiInternal.h?
Is there a better way to do/design this?
You can build sample.c without including apiInternal.h and the structure definition.
Within api.h drop the #include "apiInternal.h". Instead, declare the structure, this is called a forward declaration, (easiest to drop the typdef) so api.h will look like:
struct internalStruct;
struct internalStruct* API_init();
extern void API_set_member1(struct internalStruct* apiStruct, int value);
extern void API_set_member2(struct internalStruct* apiStruct, int value);
This works because the compiler can build sample.c as it only needs to know the size of the pointer rather than the complete structure declaration. You then only need to include apiInternal.h within your library code. You won't need to distribute apiInternal.h to your users.
If you library code has multiple files, then you will need apiInternalh.h. Each of you library source files will include apiInternal.h. If you library code is a single file, then I typically just define the structure at the top of the library C file, the extra header is not necessary.
This is called an opaque pointer. The Wikipedia article provides an additional example. This is nice way of achieving information-hiding from within C.
So I'm following along in Head First C and we're on a chapter where we learn to compile multiple files together. One of them is encrypt.c.
#include "encrypt.h"
void encrypt(char *message)
{
char c;
while (*message) {
*message = *message ^ 31;
message++;
}
}
The encrypt.h file repeats the first line with a semicolon at the end, so why do I need it? I understand why I would need header files to fix the problem of using a function before it's defined, so I could understand #including it in a file that uses encrypt.c, but why would I need it inside encrypt.c? Is it just one of those "because" reasons?
If the contents of encrypt.c are shown in their entirety, then you don't need the header. But it's still a good idea to include it because:
If one function in the file uses another, then the order of definition matters because the callee must be defined before the caller. It's even possible to have two functions A and B where each calls the other, in which case you cannot get the code to compile without at least one forward declaration. Including the header with the forward declarations solves these problems.
Consuming the header just like your client code does is a good way to have the compiler point out discrepancies between the signatures in the forward declarations and the actual function definitions. If undetected this kind of problem can lead to "interesting" behavior at runtime and lots of hair-pulling.
You're right, if that's all encrypt.h declares, you don't need to include it in the .c file.
You mostly do it for consistency.
Imagine that you change encrypt.c to void encrypt(char *message, int i) { }
If you don't include encrypt.h you won't notice that the other files in your application haven't been updated to pass the new parameter. If you update encrypt.h and encrypt.c at the same time the compiler can do checking for you.
It's good style.
Sometimes, C-file with function implementation and C-file with function usage shares common declarations - types/structures, This shares declarations places at the H-file.
For ex.
[enc.h]
typedef enum {S,F} Res;
EN encode();
[enc.c]
#include "enc.h"
Res encode() { ... }
[other.c]
Res res;
res = encode();
It is prototyping the function
http://en.wikipedia.org/wiki/Function_prototype
Then you include the header in a another *.c-file the compiler knows in this way that anywhere else is the function definition.
This ist like:
#include <stdio.h>
int main (void)
{
afun();
return 0;
}
void afun (void)
{
printf("hello\n");
}
Now the compiler doesn't know what to do with afun() in the main function. Because it was'nt defined. So it will lead into an compiler error.
So you add the declaration at the beginning or bevore the first usage:
#include <stdio.h>
void afun(void);
int main (void)
{
afun();
return 0;
}
void afun (void)
{
printf("hello\n");
}
Know the compiler knows the deklaration of afun and hopes anythere else the function is defined. With header files it is possible to use precompiled c-code. The only thing the compiler is needed is the deklaration of the function.
I'm trying to minimize interdependence of #include files as a general practice.
In xxx.h I have:
struct my_struct; // partial decl to satisfy use of my_struct*
void funct(struct my_struct* ms); // uses the partial def
How to do a similar partial decl with a typedef'd struct?
I have an actual decl in some third #include that looks like (say in yyy.h):
typedef struct my_data_s {
int ival;
... struct's other components ...
} my_data_t;
I just want a representative decl in xxx.h that reference the typedef:
typedef struct my_data_s my_data_t; // actual full decl is elsewhere
void funct2(my_data_t* md);
This attempt causes 'redefinition of typedef my_data_t' error. (Using gcc 4.4.3 / Ubuntu 10.4) Other random search attempts (e.g., add '{}' to typedef) also give errors.
I know the compiler only needs to know that the function requires a pointer, so it seems like this should be possible. So far, found nothing that compiles w/o errors/warnings.
I've looked at the other questions and answers, could not find this problem addressed. Seems like there should be a well-known way to do this(?!) (I know that I can #include yyy.y whenever I #include xxx.h - trying to avoid such dependencies.) Thanks.
Have you tried the simple approach:?
xxx.h
struct my_data_s;
typedef struct my_data_s my_data_t;
yyy.h
#include "decl.h"
struct my_data_s {
int foo;
};
C99 doesn't allow to repeat a typedef, C11 does.
Just do the typedef only once and always have it first:
typedef struct my_data my_data;
There also is no need to chose different names for the struct tag and the typedef identifier.
Here's what our group decided to do. It represents a compromise of several conflicting requirements/desires. I am posting to show another approach, so readers of the post have some variety to choose from. It represents the best answer for our situation.
obj_a_defs.h
// contains the definition
// #include'd only by other .h files
...
#define ... // as needed for struct definition
...
typedef struct obj_a {
...
} obj_a;
obj_a.h
// contains the 'full info' about obj_a: data and behaviors
// #include'd by other .c files
...
#include "obj_a_defs.h"
...
// declares functions that implement
// the behaviors associated with obj_a
obj_a.c
...
#include "obj_a.h"
...
// implementations of functions declared in obj_a.h
obj_b.h
// a 'user' of obj_a that uses obj_a as arg
#include "obj_a_defs.h" // to get the typedef
...
int some_b_funct(obj_a* obja, ...);
...
obj_b.c
// Defines the 'contract' that this implementation
// is meeting.
#include "obj_b.h"
...
// This .c file includes obj_a.h only if it
// uses the functions defined for obj_a.
// If obj_a is used only to 'pass through'
// to other modules, there's no need for
// this include.
#include "obj_a.h" // only if obj_b uses
...
// obj_b's function implementations
Rationale / Conditions
typedef and struct kept together
a .c file that uses obj_X must #include "obj_X.h"
to show that use
avoid .h files including other .h files in general;
only 'defs.h' files are #include'd in .h files.
avoid #include'ing a file just to handle dependencies;
IOW avoid #include'ing obj_a.h just because it's used in obj_b.h
I'm just getting started with modular programming in C. I think I'm doing something wrong with the inclusions, because I'm getting a lot of conflicting types for 'functionName' and previous declaration of 'functionName' was here errors. I did put inclusion guards in place.
Do you know a clear tutorial that explains modular programming in C, especially how the inclusions work?
Update: I have tried to isolate my issue. Here's some code, as requested.
Update 2: updated code is below. The errors have been updated, too.
/*
* main.c
*/
#include <stdio.h>
#include "aStruct.h"
int main() {
aStruct asTest = createStruct();
return 0;
}
/*
* aStruct.h
*/
#ifndef ASTRUCT_H_
#define ASTRUCT_H_
struct aStruct {
int value1;
int value2;
struct smallerStruct ssTest;
};
typedef struct aStruct aStruct;
aStruct createStruct();
#endif /* ASTRUCT_H_ */
/*
* smallerStruct.h
*/
#ifndef SMALLERSTRUCT_H_
#define SMALLERSTRUCT_H_
struct smallerStruct {
int value3;
};
typedef struct smallerStruct smallerStruct;
smallerStruct createSmallerStruct();
#endif /* SMALLERSTRUCT_H_ */
/*
* aStruct.c
*/
#include <stdio.h>
#include "smallerStruct.h"
#include "aStruct.h"
aStruct createStruct() {
aStruct asOutput;
printf("This makes sure that this code depends on stdio.h, just to make sure I know where the inclusion directive should go (main.c or aStruct.c).\n");
asOutput.value1 = 5;
asOutput.value2 = 5;
asOutput.ssTest = createSmallerStruct();
return asOutput;
}
/*
* smallerStruct.c
*/
#include <stdio.h>
#include "smallerStruct.h"
smallerStruct createSmallerStruct() {
smallerStruct ssOutput;
ssOutput.value3 = 41;
return ssOutput;
}
This generates the following error messages:
At aStruct.h:10
field 'ssTest' has incomplete type
At main.c:8
unused variable `asTest' (this one makes sense)
The base of inclusion is to make sure that your headers are included only once. This is usually performed with a sequence like this one:
/* header.h */
#ifndef header_h_
#define header_h_
/* Your code here ... */
#endif /* header_h_ */
The second point is to take care of possible name conflicts by handling manually pseudo namespaces with prefixes.
Then put in your headers only function declarations of public API. This may imply to add typedefs and enums. Avoid as much as possible to include constant and variable declarations: prefer accessor functions.
Another rule is to never include .c files, only .h. This is the very point of modularity: a given module dependant of another module needs only to know its interface, not its implementation.
A for your specific problem, aStruct.h uses struct smallerStruct but knows nothing about it, in particular its size for being able to allocate an aStruct variable. aStruct.h needs to include smallerStruct.h. Including smallerStruct.h before aStruct.h in main.c doesn't solve the issue when compiling aStruct.c.
The multiple definition problem is most likely coming from the way you're including the code. You are using #include "aStruct.c" as opposed to #include "aStruct.h". I suspect you are also compiling the .c files into your project in addition to the #include. This causes the compiler to become confused due to the multiple definitions of the same function.
If you change the #include to #include "aStruct.h" and make sure the three source files are compiled and linked together, the error should go away.
Such errors mean that function declaration (return type or parameter count/types) differs from other function declarations or function definition.
previous declaration message points you to the conflicting declaration.