C Header Files - Dividing the main code - c

I am doing my first "big/medium" project for a school work and I need to divide my code into some other c files. My doubt is if it is better have many files/header files with just a few little code, or have less files/header files and a little more code/functions into them?
Thank you!
p.s. I am a newbie programmer, so be patient and try to make the explanation easy to understand.

My experience is that having code grouped into source/headers according to functionality increases ability to understand, test, maintain and reuse it.
How much code goes into each file will really depend on how complex the encapsulated functionality is. For example, I have a source file containing functions to create and append to WAV files. They are relatively small, and because they are cohesive, I can use them in whatever project I have that needs to create WAV files without bringing in a lot of other baggage. Other files may be large (or very large) but if the functionality is cohesive, I get the same benefits.
One thing that tripped me up when I started doing this was “multiple inclusions” caused by including the same header in a project multiple times without “protecting” it. Since you say you are a newbie, I’ll add a quick sample of what you can do to prevent it.
/**
#file my_header.h
*/
ifndef MY_HEADER_H // <- Prevents multiple inclusions
#define MY_HEADER_H // <- ...
#ifdef __cplusplus // <- Allows this to be called from c++
extern "C" { // <- See "name mangling for more info.
#endif // <- ...
/**************************/
// your stuff goes here
struct my_struct
{
// ...
};
// function prototypes, etc.
/**************************/
#ifdef __cplusplus
}
#endif
#endif // MY_HEADER_H

Related

Translate headers to Cython

Is it feasible for Cython to have the ability to translate C headers Cython-directives? (See here, in Conditional Compilation).
A similar suggestion was made here too.
In my case, I would like these C-directives in my .h:
/* myheader.h */
#define MONIT_STEP 1 // stuff for step monit
//#define MONIT_SCATTERING 1 // monitor particle scattering
#define clight (3.0*1e10)
//#define NORM(x,y,z) (sqrt(x*x+y*y+z*z)) // maybe this is too much to ask?
to be translated to:
# cython_header.pyx
DEF MONIT_STEP = 1
DEF clight = (3.0*1e10)
So that later, I can do:
include "cython_header.pyx"
in any other .pyx code I want to compile.
Of course, I'm implying to have the hability to ignore any character after any "//" string in the myheader.h.
I left the NORM(x,y,z) commented as I don't see it trivial to implement, due to its "function" nature (i.e. it's not just copy-paste).
I thought I could catch the C-preprocessor with this (see Cython docs, in "Referencing C header files"):
cdef extern from "spam.h":
pass
but doesn't work.
Of course, I can always use this method, but I'm hoping we can be more consistent.

References to C functions determined at compile time

I am trying to think of the most elegant solution for a C program I am currently writing. Basically, I have a small core program and then lots of additional "modules" which can be called by the core program and contain most of the functionality. The idea is that the core and and each of these modules is independent.
The inclusion of these modules is determined at compile time and once I register them then the core has function pointers to the modules which it can then use.... but what is the best way of making these modules known in the first place for registration with minimal dependencies? I am currently using a "module factory" type approach, which knows about the modules and is called by the core to obtain their details for registration. But I was wondering if, through make and the preprocessor if there might be a better way of "auto-discovering" which modules have been compiled in with the core?
In the past I have used dynamically loaded libraries but in this case my modules need to be compiled in so dynamically loading a bunch of libraries from a directory and solving it that way is not an option.
I'm not quite sure if I understand the question, but I suppose you could as always create something semi-obscure with macros. I wouldn't really recommend it, but for what it is worth...:
Suppose you have one module called "module_this" and another called "module_that". There's also "module_missing" which isn't compiled with the program.
You could then create something like:
module_this.h
#ifndef MODULE_THIS // your ordinary header guard
#define MODULE_THIS module_this, // add a function name plus a comma
void module_this (void);
#endif
module_that.h
#ifndef MODULE_THAT // your ordinary header guard
#define MODULE_THAT module_that, // add a function name plus a comma
void module_that (void);
#endif
core.c
#include "something that includes all linked files.h" // generate this externally
#ifndef MODULE_THIS // this module is compiled
#define MODULE_THIS // so it wont get defined here
#endif
#ifndef MODULE_MISSING // module that was not compiled
#define MODULE_MISSING // will get defined as empty macro
#endif
#ifndef MODULE_THAT // this module is compiled
#define MODULE_THAT // so it wont get defined here
#endif
typedef void(*module_t)(void); // your function pointer type to use
static const module_t MODULE_TABLE [] = // list of all existing modules
{
MODULE_THIS // note absence of commas
MODULE_MISSING
MODULE_THAT
};
#define MODULES_N ( sizeof(MODULE_TABLE) / sizeof(module_t) )
...
printf("There are %d modules in the project.", MODULES_N);
This relies on a header file which is created from scripts/the make file, containing a number of #include.

best-practice on C header files with #ifndef #define #endif

what is concerned best practice regarding the following "pattern"?
#ifndef BLAFOO_H
#define BLAFOO_H
/* ...
* ...
*/
#endif /* BLAFOO_H */
how should i name the header in the #define directive? i've seen all from said BLAFOO_H to __BLAFOO_H to _BLAFOO_H_ etc..
Name them BLAFOO_H (personnally I use BLAFOO_H_ where BLAFOO is the header file name ).
Make sure your BLAFOO doesn't clash with other files/libraries/etc. you're using, e.g. have your project and/or module name be parth of that name.
Identifiers starting with a _ is reserved for the implementation/compiler, so don't use that.
I use an UUID that is my guarantee that #define not clashed with others. I've seen it somewhere and decided to use it as well.
My pattern is like this: __<filename>_H_<uuid>__,
eg. #define __TYPES_H_79057761_16D6_478A_BFBC_BBF17BD3E9B9__ for a file named types.h
As with other C-style questions, just be consistent. There is no way that you are going to know the namespace every library that someone might link with your program in the future. Why? Many of them have not been written yet :)
As such, its not a question of include guards, its a question of what to name the header in the first place.
I might come up with some cool new string utilities, and name the header strutil. That's a bad idea, because (surely) someone else has come up with cool new string utilities and named the header the same.
So, I name mine post_strutils.h and:
#ifndef POST_STRUTILS_H
#define POST_STRUTILS_H
/* code */
#endif
I may even call it post_str_utils.h and define the include guards appropriately because I know that I have a very common last name. Finding a namespace is sometimes difficult. Simply using one offers no guarantee that someone else did a search prior to releasing something to the wild. Be as unique as possible.
Depending on where someone tells their compiler to search for headers, its not just namespace conflicts that come into play, its also file names. Do your best to name the header uniquely, then write the include guard to match it. Someone might want to #error if the header has been included multiple times, if only to cut #include directives that aren't needed, using a UUID kind of makes doing so confusing, since it doesn't match (or even resemble) the file name of the header in question. It also makes grep/awk(or similar) powered lint scripts harder to write.
I'm not saying you should name every library / module after yourself, but do take care to make the public header file names unique. A quick conference with a search engine will tell you if you hit on an unused namespace. Please, let the include guards match (or at least closely resemble) the header. Again, consistency is highly praised. From your example, I'd expect:
int blahfoo_init(void);
double blahfoo_getval(blahfoo_t *blah);
If you go through the bother of finding a unique namespace, be sure to use it :)
The only real requirement is that it won't conflict with another project that uses the same name for its file. For all of the projects I've seen, it usually completely quantifies the namespace (or whatever folder the file is in for C) along with the project name. Sometimes it includes the date the file was created too.
So if you're working on project ABC in folder DEF today, then you could do:
#ifndef ABC_DEF_BLAFOO_H_05_30_2010
And this is very unlikely to conflict with anything.
It doesn't really matter as long as it's not likely to be used anywhere else. I usually go with something like BLAFOO_H_INCLUDED.

Separate specific #ifdef branches

In short: I want to generate two different source trees from the current one, based only on one preprocessor macro being defined and another being undefined, with no other changes to the source.
If you are interested, here is my story...
In the beginning, my code was clean. Then we made a new product, and yea, it was better. But the code saw only the same peripheral devices, so we could keep the same code.
Well, almost.
There was one little condition that needed to be changed, so I added:
#if defined(PRODUCT_A)
condition = checkCat();
#elif defined(PRODUCT_B)
condition = checkCat() && checkHat();
#endif
...to one and only one source file. In the general all-source-files-include-this header file, I had:
#if !(defined(PRODUCT_A)||defined(PRODUCT_B))
#error "Don't make me replace you with a small shell script. RTFM."
#endif
...so that people couldn't compile it unless they explicitly defined a product type.
All was well. Oh... except that modifications were made, components changed, and since the new hardware worked better we could significantly re-write the control systems. Now when I look upon the face of the code, there are more than 60 separate areas delineated by either:
#ifdef PRODUCT_A
...
#else
...
#endif
...or the same, but for PRODUCT_B. Or even:
#if defined(PRODUCT_A)
...
#elif defined(PRODUCT_B)
...
#endif
And of course, sometimes sanity took a longer holiday and:
#ifdef PRODUCT_A
...
#endif
#ifdef PRODUCT_B
...
#endif
These conditions wrap anywhere from one to two hundred lines (you'd think that the last one could be done by switching header files, but the function names need to be the same).
This is insane. I would be better off maintaining two separate product-based branches in the source repo and porting any common changes. I realise this now.
Is there something that can generate the two different source trees I need, based only on PRODUCT_A being defined and PRODUCT_B being undefined (and vice-versa), without touching anything else (ie. no header inclusion, no macro expansion, etc)?
I believe Coan will do what you're looking for. From the link:
Given a configuration and some source code, Coan can answer a range of questions about how the source code would appear to the C/C++ preprocessor if that configuration of symbols had been applied in advance.
And also:
Source code re-written by Coan is not preprocessed code as produced by the C preprocessor. It still contains comments, macro-invocations, and #-directives. It is still source code, but simplified in accordance with the chosen configuration.
So you could run it twice, first specifying product A and then product B.

Purpose of: #define, #include, #undef

What would the purpose of this construct in a c file be?:
#define _TIMERC
#include "timer.h"
#undef _TIMERC
I am aware of the guard for preventing multiple inclusion of a header file. This doesn't appear to be whats happening though.
thanks!
Here's a scenario to illustrate...
Lets say that timer.h provides a macro tick_count() that returns the number of timer interrupts that occured.
One module (rpm_reader.h) using timer A for interval timing:
#define _TIMERA
#include "timer.h"
#undef _TIMERA
In another module (lap_time.h) is using timer C for its interval timing
#define _TIMERC
#include "timer.h"
#undef _TIMERC
The rpm_reader would return the tick count from timer A when it called tick_count() and lap_time would get its count from timer C.
(My apologies for answering my own question, but asking the question helped me come to this revelation.)
Often times a library header file will have multiple options, that are enabled and disabled by macro defines. This will enable such an option.
More typically these are set at a global scope by configuring your build system to add (for eg with gcc) -D_TIMERC to the compilers command line.
I was wondering if it could be this:
The header file in this case is intended to allow multiple inclusions with different defines established before the each #include.
If in the timer.h there is a block of code (interrupt code) for timers A, B and C for each timer in the microcontroller. In some cases timer A is required in one module and timer C is required in another module.
I think your self-answer is right. There is most likely conditional stuff in the included header and the "calling" file knows which specific set of conditional "stuff" it wants to include.
It does not necessarily have to do with multiple includes - it can just be special cases depending on the "calling" context.
I am not exactly sure why one would undefine though. I can't think of a case where I would mix and match so not sure why an undefine is necessary.
At the risk of stating the obvious, "timer.h" expects to have _TIMERC and the rest of your code does not.
Clearly not good practice in the general case, but I have seen similar when including third party code. Can get nasty when you have #defs that clash...
For the record, common practice to avoid multiple includes of the same header file is to put the guard in the file itself, not to rely on some external define... ^_^
The headers start with:
#ifndef header_name_h
#define header_name_h
and end with:
#endif
Of course, the def style can vary.
Thus, on first inclusion, we go past the #ifndef (not yet defined) and we set the macro.
On second inclusion, if any, we just jump to end of file, nothing is included.

Resources