Define data structures from configuration files - c

I'm not new to C programming but I havn't got the chance to touch it for a lot of time.
I'd like your advice on a way to define data structures (struct) which are defined in a configuration file. At the moment, I haven't defined the structure for the configuration file but I'm guessing it will be something like ini file.
Basically I'm working on Windows and Linux so I'd love an answer for both OS.

I'd like your advice on a way to define data structures (struct) which are defined in a configuration file
The simplest method, by far, would be to use header (.h) files as your configuration files. You could include them into your project like so:
#include CONFIG_FILE
... and introduce them during compilation like so:
cc -D'CONFIG_FILE="path/to/config.h"' path/to/source/files.c
If you wrap all of your config values into function-like-macros from the very start, this should be nice and flexible; you shouldn't have a problem generating clean structs from your INI files.
I'm guessing it will be something like ini file
I should point out that in the world of C, define has a very strict meaning, and to define data structures (struct) can only be done in C source files (or header files, which are later included into source files).
Suit yourself! My recommendation would give you an interface that allows you to put the lexing/parsing on hold until a (much) later point in time (i.e. when you have the time to write a full-fledged INI-to-C-header compiler, because that's what you're asking about), and give you an interface with which to fill in the blanks, so to say.

Related

Why use separate source files?

I'm learning C, coming from scripted languages background it is highly intriguing and rather confusing.
A brief story of how I got to this question:
At first I was confused why I can't include a source (.c) file in another source file, then I found out that function declarations repeat. Then I found out about header files (.h) and was confused, why I have to declare a function in one file then define in another, then if something changes I have to go edit 2 files, so I started defining functions in header files. Then I found out that #ifndef doesn't work across separate source files, so here's the question I can't yet find the answer to:
Why do I even have to use separate source files? Why can't I just have 1 source file and put all of my other code/function definitions in header files, this way I'm going to have things defined once and included once in the final build?
Now don't get me wrong, I'm not thinking I'll start a revolution, I'm just looking for answers as to why this is not how it works.
If you think beyond small learning programs, there are several benefits to splitting code into multiple source files.
Code Organization
Large programming projects can have millions of lines of code. You don't want to have files that big! Editors will probably have trouble handling it. Human beings will have trouble understanding it. Multiple developers would have conflicts all touching the same file. If you separate the code by purpose, it will be much easier to handle.
Build Times
Many code changes are small, while compilation time can be expensive. Compilers typically work on a file at a time, not parts of files. So if you make a tiny change and then have to rebuild the entire project, that can be very time consuming. If your code is separated into multiple source files, making a change in one of them means you only have to recompile that file.
Reusability
Frequently, code can be reused for more than one program. If you have all your code in one source file, you'll have to go and copy that code into another file to reuse it. Of course, now if it has a bug you have two places to fix it. Not good.
Let's say, for example, you have code that uses a linked list. If you put the linked list code into its own source file, you can then simply link that into another program. If there's a bug, you can fix it in one place, recompile, and then re-link the programs that use it.
You can use a single source file for some (small) projects.
For many projects though, it makes sense to divide the source in different source files according to their function.
Let's say your making a game.
Have all the user interface code in its source file.
Have all the computer move algorithms in its source file.
...
Have the main() function which ties it all together in its source file.
Then, to compile for PC you do gcc game.c algo.c ui-pc.c, to compile to android you do gcc game.c algo.c ui-android.c ..., to compile a brand new algorithm you though up and don't know if it's good gcc game.c algo-test.c ui-pc.c
Header files help keep everything in sync. And they're a good place for documentation.

Is it ok to store functions in header files that aren't shared across multiple source files?

What if you have a minimal amount of structures, functions and macros but want to exclude them from the source file to convert the source code into a more concise and readable format and reduce the amount of lines of code.
Is structures, functions or macros/data in general accessible/viewable from examining the binary even if the data is not called within the source code? And if so how?
For the sake of readability is it safe to cut structures, functions and macros from a source file into a header file that is used by multiple source files even if some source files don't use all of the structures, functions and macros (for small header files)?
Is structures, functions or macros/data in general accessible/viewable
from examining the binary even if the data is not called within the
source code?
Depends on what you build. If you build a library (.a, .so, .lib, .dll, whatever) they're probably in there and everything in that library is accessible in some way. If you build an executable the linker will most likely remove unused code.
Have a look at nm
For the sake of readability is it safe to cut structures, functions
and macros from a source file into a header file that is used by
multiple source files
Yes and no. Put declarations of functions/structs in header files and their implementations in .c files. Don't put a lot of unrelated functions and structs in one header. You end up including all those declarations in every source file even though you're using 5% of them. That means extra work for your compiler, probably some extra work for your linker and extra work for your and future programmers brains when reading all this unnecessary stuff.
So, guessing what's happening in your code base, you probably want to put them in seperate header files.
Be careful when using macros and even more when putting them in header files. You should avoid this most of the time.
even if some source files don't use all of the structures, functions
and macros
That is quite common. You include some standard C headers too and don't use all of the functions and structs in there right? Just (as I said) put together what belongs together.

What goes in an "inc" includes folder in a project?

I'm putting my Simplicity Studio project into TortoiseSVN. I've been told to create an inc (includes) folder and use it. What is it? Why would I use it?
It's just a convention, not something that is required. For large projects it is often used to hold any file that is included from another file, i.e.:
#include "headerFile.h"
You might ask the person who "told" you to do that - it is not a language or tool-chain requirement.
The preprocessor does not care where the include files are so long is you tell it (either in the #include directive itself, by command line options or environment variables). Putting all headers in a folder separate to the associated .c files is a common practice but often a habit rather than for any good reason. It is useful when the headers relate to some static, shared library, or DLL where the headers are to be distributed with the compiled object code.
In other cases it is arguably simpler and more useful to keep the headers and the associated .c files in the same directory as each other. That allows for example "localised" headers to be included using double-quotes without needing to explicitly tell the preprocessor which paths to search.

What is a C header file? [duplicate]

This question already has answers here:
Closed 13 years ago.
Possible Duplicates:
[C] Header per source file.
In C++ why have header files and cpp files?
C++ - What should go into an .h file?
Is the only reason header files exist in C is so a developer can quickly see what functions are available, and what arguments they can take? Or is it something to do with the compiler?
Why has no other language used this method? Is it just me, or does it seem that having 2 sets of function definitions will only lead to more maintenance and more room for errors? Or is knowing about header files just something every C developer must know?
Header files are needed to declare functions and variables that are available. You might not have access to the definitions (=the .c files) at all; C supports binary-only distribution of code in libraries.
The compiler needs the information in the header files to know what functions, structures, etc are available and how to use them.
All languages needs this kind of information, although they retrieve the information in different ways. For example, a Java compiler does this by scanning either the class-file or the java source code to retrieve the information.
The drawback with the Java-way is that the compiler potentially needs to hold a much more of information in its memory to be able to do this. This is no big deal today, but in the seventies, when the C language was created, it was simply not possible to keep that much information in memory.
The main reason headers exist is to share declarations among multiple source files.
Say you have the function float *f(int a, int b) defined in the file a.c and reused in b.c and d.c. To allow the compiler to properly check arguments and return values you either put the function prototype in an header file and include it in the .c source files or you repeat the prototype in each source file.
Same goes for typedef etc.
While you could, in theory, repeat the same declaration in each source file, it would become a real nightmare to properly manage it.
Some language uses the same approach. I remember the TurboPascal units being not very different. You would put use ... at the beginning to signal that you were going to require functions that were defined elsewhere. I can't remember if that was passed into Delphi as well.
Know what is in a library at your disposal.
Split the program into bite-size chunks for the compiler. Compiling a megabyte of C files simultaneously will take more resources than most modern hardware can offer.
Reduce compiler load. Why should it know in screen display procedures about deep database engine? Let it learn only of functions it needs now.
Separate private and public data. This use isn't frequent but you may implement in C what C++ uses private fields for: each .c file includes two .h files, one with declarations of private stuff, the other with whatever others may require from the file. Less chance of a namespace conflict, safer due to hermetization.
Alternate configs. Makefile decides which header to use, and the same code may service two different platforms given two different header files.
probably more.

Header per source file

I'm trying to understand the purpose behind one header per each source file method. As I see it, headers are meant for sharing function declarations, typedef's and macro's between several files that utilize them. When you make a header file for your .c file it has the disadvantage that each time you want to see a function declaration or macro you need to refer to the header file, and generally it is simpler that everything is in one source file (not the whole software, of course).
So why do programmers use this method?
The header files in C separate declarations (which must be available to each .c file that uses the functions) from the definitions (which must be in one place). Further, they provide a little modularity, since you can put only the public interface into a header file, and not mention functions and static variables that should be internal to the .c file. That uses the file system to provide a public interface and private implementation.
The practice of one .h file to one .c file is mostly convenience. That way, you know that the declarations are in the .h file, and the definitions in the corresponding .c file.
Logical, structured organisation and small source files enable:
faster, better programming - breaking the code into more manageable and understandable chunks makes it easier to find, understand and edit the relevant code.
code re-usability - different "modules" of code can be separated into groups of source/header files that you can more easily integrate into different programs.
better "encapsulation" - only the .c files that specifically include that header can use the features from it, which helps you to minimise the relationships between different parts of your code, which aids modularity. It doesn't stop you using things from anywhere, but it helps you to think about why a particular c file needs to access functions declared in a particular header.
Aids teamwork - two programmers trying to change the same code file concurrently usually cause problems (e.g. exclusive locks) or extra work (e.g. code merges) that slow each other down.
faster compiles - if you have one header then every time you make a change in it you must recompile everything. With many small headers, only the .c files that #include the changed header must be rebuilt.
easier maintainability & refactoring - for all the above reasons
In particular, "one header for each source file" makes it very easy to find the declarations relevant to the c file you are working in. As soon as you start to coalesce multiple headers into a single file, it starts to become difficult to relate the c and h files, and ultimately makes building a large application much more difficult. If you're only working on a small application then it's still a good idea to get into the habit of using a scalable approach.
Programmers use this method because it allows them to separate interface from implementation while guaranteeing that client code and implementation agree on the declarations of the functions. The .h file is the "single point of truth" (see Don't Repeat Yourself) about the prototype of each function.
(Client code is the code that #include's the .h file in order to use the exported functions, but does not implement any of the functions in the .h.)
Because, as you said yourself, it is not feasible to put the "whole software" into one source file.
If your program is very small, then yes it's is simpler just to put everything in one .c file. As your program gets larger, it becomes helpful to organize things by putting related functions together in different .c files. Further, in the .h files you can restrict the declarations you give to declarations of things that are supposed to be used by things in other .c files. If a .c file doesn't contain anything that should be accessible outside itself, it needs no header.
For example, if .c has function foo() and fooHelper(), but nobody except foo() is supposed to call fooHelper() directly, then by putting foo() and fooHelper() into foo.c, only putting the declaration of foo() in foo.h, and declaring fooHelper() as static, it helps to enforce that other parts of your program should only access foo() and should not know or care about fooHelper(). Kind of a non object-oriented form of encapsulation.
Finally, make engines are generally smart enough to rebuild only those files which have changed since the last build, so splitting into multiple .c files (using .h files to share what needs to be shared) helps speed up builds.
You only put in your header file the bare minimum that other source files need to "see" in order to compile. I've seen some people that put everything non-code into the header file (all typedefs, all #define's, all structures, etc.) even if nothing else in the codebase will be using those. That makes the header file much harder to read for yourself and those who want to use your module.
You don't need one header per source file. One header per module, containing the public interface, and maybe an additional header containing private declarations etc shared between files in that module.
Generally a header for a source file method means that you declare only the functions from that compilation unit in that header.
That way you don't pollute with declarations you don't need. (in large software project might be a problem)
As for separate compilation units, these speed up the compilation and can help you avoid collisions if private symbols are declared static.

Resources