C project with multiple files (header files) - c

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.

Related

define array length struct with global constant from other file

In my model I have quite some parameters that are used by a lot of different functions.
To make changing settings easy, I want to use one file for all my paramaters, keeping it sepperate from any of the "real programming".
That file is called parameters.c
In it, all parameters are defined like:
#define N 1000
#define T 1373
In a different c file (MyLib.c), I create a struct type:
typedef struct Model{
struct Element el[N];
};
both files are included in my main script using:
#include "parameters.c"
#include "MyLib.c"
The project can not be build this way. However, if I move the line
#define N 1000
from parameters.c to MyLib.c, it works.
I could just create the struct to have an array that is larger than any N value I'd use, but that doesn't seem like the correct way to do it.
Is there a correct way to implement this, or would I indeed have to create the large array? (in the comments it was said the definition of correct is too broad. In this instance I mean memory efficient. I don't want to allocate a much larger chunck of memory than I need to.)
Thanks in advance.
Is there a correct way to implement this
You library may look like this:
// parameters.h
#ifndef PARAMETERS_H_
#define PARAMETERS_H_
// documentation
#define PARAMETERS_COUNT_OF_ELEMENTS 1000
// this parameters does that and that
#define PARAMETERS_DESCRIPTIVE_NAME 1373
// ^^^^^^^^^^^ - consistent namespace naming
#endif
// mylib.h - safe yourself trouble and DoN'T mIx UppErCaSe with lOwErcAsE
// escapecially in header names
// subjectively, I do not like pascal case - snake case rule them all!
#ifndef MYLIB_H_
#define MYLIB_H_
#include "parameters.h"
#include "element.h" // for struct element
/// This structure represents a model in our library.
struct mylib_model {
// ^^^^^^ - consistent namespace naming
/// These are super important elements we deeply care about.
struct element el[PARAMETERS_COUNT_OF_ELEMENTS];
};
/**
* #brief this function does that and that
* #return 0 on success, otherwise error
*
* Write documentation keeping consistent style, for example
* use doxygen.
*/
int mylib_do_something(struct mylib_model *the_model);
#endif
// mylib.c
#include "mylib.h"
int mylib_do_something(struct mylib_model *t) {
// do something here
// return 0 on success, otherwise document error codes, or use the ones from errno.h
return 0;
}
// main.c
#include "mylib.h"
int main() {
struct mylib_model model = {0};
int err = mylib_do_something(&model);
if (err != 0) { abort(); }
return 0;
}
Your parmeters.h is very similar to the way autoconf projects generate config.h present in many GNU projects. Many projects use a configuration file, sometimes generate automatically by a build system. Nowadays if choosing build automation software I would recommend cmake. Other links: kernel coding style and google coding style.

C - Include only specific function

Alongside main.c file, I have following my_custom_data_structure.c file in my project. My my_custom_data_structure.c file contains a lot of variables, functions, etc.
I am using #include "my_custom_data_structure.c" directive in main.c.
Problem
I would like to import only single function called foo from my_custom_data_structure.c. I don't need all the variables and functions, which are declared in my_custom_data_structure.c file.
Any insights appreciated.
File structure
-
|- main.c
|- my_custom_data_structure.c
Content of my_custom_data_structure.c
#include <stdio.h>
int DELAY = 20;
int SPEED = 7;
char GRANULARITY_CHAR = 'g';
unsigned int RANGE = 3;
void foo(){
// TODO: In future, this function will print SPEED.
printf("foo works!");
}
/*
The rest of this file is filled by a lot
of code, which is not needed for main.c
*/
Content of main.c
#include <stdio.h>
#include "my_custom_data_structure.c"
int DELAY = 3;
int main(){
foo();
printf("Delay is %d", DELAY);
return 0;
}
UPDATED: Added working example
The usual way is to compile them separately. So you have your main.c, and your extra.c, and you should create a extra.h (and include it in main.c).
In this extra.h, put in declarations for anything that is to be exported from your extra.c file.
For example any functions that should be available to other files. All other functions should be declared/defined only in your extra.c as static, so that they are not available as symbols to be linked when main.c is compiled.
Normally, you don't include source files (.c) inside other source files (or inside headers). It's possible (and occasionally necessary), but it isn't usual.
Unless you've designed the my_custom_data_structure.c to allow you to specify which functions are to be compiled, you get everything in the file. For example, you could use:
#ifdef USE_FUNCTION1
void function1(void *, …)
{
…
}
#endif /* USE_FUNCTION1 */
around each function, and then arrange to
#define USE_FUNCTION1
before including the source, but that's not usually a good way of working. It's fiddly. You have to know which functions you use, and which other functions those need, and so on, and it is vulnerable to changes making the lists of USE_FUNCTIONn defines inaccurate. Of course, the source code might have blocks of code like:
#ifdef USE_FUNCTION1
#define USE_FUNCTION37
#define USE_FUNCTION92
#define USE_FUNCTION102
#endif /* USE_FUNCTION1 */
so that if you say you use function1(), it automatically compiles the other functions that are required, but maintaining those lists of definitions is fiddly too, even when the definitions are USE_MEANINGFUL_NAME instead of a number.
Create a header (my_customer_data_structure.h) declaring the functions and any types needed, and split the implementation into many files (mcds_part1.c, mcds_part2.c, …).
Compile the separate implementation files into a library (e.g. libmcds.a), and then link your program with the library. If it's a static library, only those functions that are used, directly or indirectly, will be included in the executable.

How to use the same structure accross multiple source files?

I have 3 source files: matrix.c, tetramino.c and learntris.c (which includes the headers tetramino.h and matrix.h, linking it with the respective files). I have a structure: struct tetramino that is need in all these files. After reading this question and its answers- How to use a defined struct from another source file?, I created a header file structure.h and now my files look like this:
In structure.h:
typedef struct tetramino
{
int type;
char *p;
}tetramino;
In matrix.h:
#include"structure.h"
int print_matrix(void);
int clear_matrix(void);
In tetramino.h:
#include"structure.h"
int rotate(void);
int set_tetramino(void);
And finally, in the main learntris.c file contains:
#include"structure.h"
#include"matrix.h"
#include"tetramino.h"
Now, upon compiling them, I get these errors:
error: redefinition of 'struct tetramino'
and
error: conflicting types for 'tetramino'
Where is the problem?
When you #include <structure.h> in all of your files, it includes them each time. This causes it to try to define the structure each time.
Use include guards to ensure that the header file will be included once.
#ifndef STRUCTURE_H
#define STRUCTURE_H
typedef struct tetramino
{
int type;
char *p;
}tetramino;
#endif /* STRUCTURE_H */
It is suggested to use guards in all your header files, however this is not a must, but a very good practice.
As stated by Neroku, you could use #pragme once instead. Read more here.
Besides guards, that other answers explain, it is not good practice to include .h files in .h files as you now cannot control the order in which they are included. Also, a change to a .h file can now result in all your c files needing recompilation, even if they are not affected by the change (that is, you create unnecesary dependencies).
You should have included structure.h only in the C files and then only when the C file needs to know about the structure.
#include literally pastes the contents of the included file into the location of the #include directive. So in your example, you end up with 3 times the same structure declaration.
The canonic solution for this is guard macros:
#ifndef EXAMPLE_HEADER_FILE_H
#define EXAMPLE_HEADER_FILE_H
struct exampleStruct
{
// ...
};
#endif
This way, only the first #include will actually paste the declaration, every consecutive #include will cause the preprocessor to skip the whole header because the guard macro is already defined.
Every header file should have the following structure:
#ifndef TETRAMINO_STRUCTURE_H
#define TETRAMINO_STRUCTURE_H
struct tetramino { ... };
#endif
This means that the main part of the header file is only evaluated once. The name TETRAMINO_STRUCTURE_H consists of the project name, the file name and the trailing H, meaning header.
Second, since the function declarations don't need the tetramino type, you don't need to #include "structure.h" in them. You only need these lines in the corresponding .c files.

How to prevent internal structs from being visible to the user of the API?

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.

How to partially declare a struct that is typedef'ed when in an include file

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

Resources