Why to define functions rather than include a file [closed] - c

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I was making a code and I had like 5 include files in there, I was defining functions in this file and then realized why should not I just make separate header files for all the functions and then just include them in a file at last. But, I have seen that this is not done usually. Why not? Is there a particular disadvantage of doing this?

This is not a real answer, because the question has a wrong assumption:
But, I have seen that this is not done usually.
This is not true. This is a common practice. A good example is ffmpeg.h. The header is a front-end to an extensive library.
The argument of long compilation times is bogus. Today the systems are very fast. This is only important for really huge systems, but I really don't think that you work with them. I never encountered such systems myself.
And compilation times aren't execution times. This is another misconception.
For your convenience the whole code of ffmpeg.h:
#ifndef _INCLUDE_FFMPEG_H_
#define _INCLUDE_FFMPEG_H_
#ifdef HAVE_FFMPEG
#include <avformat.h>
#endif
#include <stdio.h>
#include <stdarg.h>
/* Define a codec name/identifier for timelapse videos, so that we can
* differentiate between normal mpeg1 videos and timelapse videos.
*/
#define TIMELAPSE_CODEC "mpeg1_tl"
struct ffmpeg {
#ifdef HAVE_FFMPEG
AVFormatContext *oc;
AVStream *video_st;
AVCodecContext *c;
AVFrame *picture; /* contains default image pointers */
uint8_t *video_outbuf;
int video_outbuf_size;
void *udata; /* U & V planes for greyscale images */
int vbr; /* variable bitrate setting */
char codec[20]; /* codec name */
#else
int dummy;
#endif
};
/* Initialize FFmpeg stuff. Needs to be called before ffmpeg_open. */
void ffmpeg_init(void);
/* Open an mpeg file. This is a generic interface for opening either an mpeg1 or
* an mpeg4 video. If non-standard mpeg1 isn't supported (FFmpeg build > 4680),
* calling this function with "mpeg1" as codec results in an error. To create a
* timelapse video, use TIMELAPSE_CODEC as codec name.
*/
struct ffmpeg *ffmpeg_open(
char *ffmpeg_video_codec,
char *filename,
unsigned char *y, /* YUV420 Y plane */
unsigned char *u, /* YUV420 U plane */
unsigned char *v, /* YUV420 V plane */
int width,
int height,
int rate, /* framerate, fps */
int bps, /* bitrate; bits per second */
int vbr /* variable bitrate */
);
/* Puts the image pointed to by the picture member of struct ffmpeg. */
void ffmpeg_put_image(struct ffmpeg *);
/* Puts the image defined by u, y and v (YUV420 format). */
void ffmpeg_put_other_image(
struct ffmpeg *ffmpeg,
unsigned char *y,
unsigned char *u,
unsigned char *v
);
/* Closes the mpeg file. */
void ffmpeg_close(struct ffmpeg *);
/*Deinterlace the image. */
void ffmpeg_deinterlace(unsigned char *, int, int);
/*Setup an avcodec log handler. */
void ffmpeg_avcodec_log(void *, int, const char *, va_list);
#endif /* _INCLUDE_FFMPEG_H_ */

Some people argue that putting functions in a separate file and including them through a header adds some overhead to the project and increases compilation (not execution) time. Although strictly speaking this is true, in practice the increased compilation time is negligible.
My take on the issue is more based on the purpose of the functions. I am against putting a single function per file with an associate header as this quickly becomes a mess to maintain. I do not think that putting everybody together in a single file is a good approach either (also a mess to maintain, although for different reasons).
My opinion is that the ideal trade off is to look at the purpose of the functions. You should ask yourself whether the functions can be used somewhere else or not. In other words, can these functions be used as a library for a series of common tasks in other programs? If yes, these functions should be grouped in a single file. Use as many files as you have general tasks. For instance, all functions to perform numerical integration in one file, all functions to handle file i/o in another, all functions to deal with strings in a third file and so on. In this way your libraries are consistent.
Finally, I would place a function that performs a task only meaningful for a specific program into the same file of the main function. For instance any function whose purpose is to initialize a series of variables.
But most of all, you should take any advice just as an advice. In the end of the day you should adopt the approach that makes your (or your team) development the most productive.

You should only make one "super-include-header" if you are writing some sort of API or library and want to make it easy for the user of that library to access the functions inside. The Windows OS API is the most obvious example of this, where one #include gives you access of thousands upon thousands of functions.
But even when writing such libraries, you should be wary of "super-headers". The reason why you should try to avoid them is related to program design. Object-oriented design dictates that you should strive to make isolated, autonomous modules that focus on their own task without knowing or caring about the rest of the program.
The rationale behind that design rule, is to reduce the phenomenon known as tight coupling, where every module is heavily dependant on other modules. Computer science research (like this study, for example) shows that tight coupling combined with complexity leads to far more software errors, and also far more severe errors. If a program with tight coupling gets a bug in one module, the bug might escalate throughout the whole program and cause disaster. While a bug in one autonomous module with loose coupling only leads to that particular module failing.
Each time you include a header file, you create a dependency between your program and that header file. So while it is tempting to just make one file that includes everything, you should avoid this, as it would create tight coupling between all modules in the project. It will also expose the modules to each other's global name space, possibly leading to more name space collisions with identical variable names etc.
Tight coupling is also, aside from the safety concerns, very annoying when you link/build your program. With tight coupling, suddenly your database module cannot work if something completely unrelated, like the GUI library isn't linked.

Related

how do we configure the parameter inside lib from app layer

I have very basic question on C language.
Situation
There is a library named "lib".
The library has a member of array named "tmp".
int tmp[ARRAY_SIZE];
currently ARRAY_SIZE is defined inside lib.
Even though it is treated as library, we compile the library and app at the same time.(we are in non-OS environment)
We can use static memory allocation only (no dynamic allocation)
because of embedded system environment (where using heap is likely to be avoided)
Since this is the library, we would like to be independent from application layer as much as possible
Goal
We would like to make ARRAY_SIZE configurable from app layer.
Question
In this situation, how do you modify this library to achieve the goal ?
Here is my ideas.
define "tmp" at application layer,
then pass it as a pointer to the library at initialization time.
define the MACRO at compile time, like -DARRAY_SIZE=10
create header file like lib_setting.h at app layer, the include it from lib.h
Any other ideas ?
If you were me, how do you implement ?
John
Any other ideas ?
No, these are exactly the solutions to such problems.
If you were me, how do you implement ?
It strongly depends on what the library is for and what exactly ARRAY_SIZE represent. For sure I would not call it ARRAY_SIZE, as the name ARRAY_SIZE() is used in linux kernel I'm familiar with, so I would definitely pick a LIB_unique LIB_name LIB_with LIB_prefix.
If it's a library meant for normal regular use, I would definitely go with option 1 whenever possible.
struct lib_s {
char *buf;
size_t bufsize;
};
static int lib_init(struct lib_s *t, char *buf, size_t bufsize) {
assert(t);
assert(buf);
assert(bufsize);
t->buf = buf;
t->bufsize = bufsize;
return 0;
}
int lib_dosomething(struct lib_s *t);
// client
int main() {
char mysuperbuffer[2046];
struct lib_s lib;
lib_init(&lib, mysuperbuffer, sizeof(mysuperbuffer));
}
Such design is easy to unit test. Is re-entrant. The lifetime is manageable. It's not spaghetti code. It's easy to understand and track variables. If user changes his mind, the user can choose if he wants to malloc or not. It's easy to refactor and extend later. Such design is found in many functions - fopenbuf() comes to my head from POSIX.
If it's a highly specialized library that profiling shows it's the bootleneck and the library needs super speed of execution and you don't want to waste sizeof(char*) + sizeof(size_t) bytes of memory and a lot more for indirection, I would go with option 3. Many projects use it - autotools generates a main config.h file, mbedtls.h has mbedtls/config.h file, etc.
If the configuration option is very constant and rarely changes, for example changes only when switching platforms, on windows it's something on linux it's something else, then maybe I would consider option 2, but I believe I would prefer to go option 3 anyway. Using a file is easier to track in control version systems and build systems will recompile only files that depend on a header that sees that definition. A macro passed on command line is harder to track which files use it (ie. spaghetti code) and usually when you change it's value, you have to recompile the whole project.

Interface for I/O library

When someone wants to build a C library for dealing with I/O (dealing with a specific file format), they pretty much have to provide the following:
/* usual opaque struct setup */
struct my_context;
typedef struct my_context my_context_t;
/* Open context for reading from user specified callbacks */
my_context_t* my_open_callback(void* userdata,
size_t(*read_cb)(void* data, size_t size, size_t count, void* userdata),
int(*close_cb)(void* userdata),
void(*error_cb)(const char* error_msg)
);
And then later provide some common ones:
/* Open directly from file */
my_context_t* my_open_file(const char * filename);
/* Open from an existing memory block */
my_context_t* my_open_memory(const char* buf, size_t len);
As far as as understand there are possibly others, but is this one considered to reduce inconsistencies, unsafe practices and inefficiencies in the design, or is there something else considered best practice ? Is there a name for this convention/best practice ?
These are interface design questions. A good interface provides a useful abstraction and hides implementation details. In your example, my_context_t elides some of the implementation details from your user base, provided you don't fully define the type in a public header. This provides you with the freedom to make substantial changes to your implementation without forcing your entire user base to rewrite their code. It is a very good practice, provided the rest of your abstraction is a good fit to the problem space. Sometimes you just have to commit to exposing additional detail at the interface level.

trigger function before file write operation

Let say we have a function:
void persist_result(FILE* to, unsigned char* b, int b_len) {...}
which would save some result in the given FILE* to.
Now I would like to get the data before the data is written to to, do something with it (assume encrypt it, etc..) and then call the actual IO operation, directly or indirectly.
One solution could be setting a buffer, but I don't know how to trigger my method for the encryption operation.
Also I was thinking to get some handle of file in memory, but don't know if there is any ISO way to do that?
Or any better solution?
Consider the following:
Size of the data need to be written by the persist_result is unknown, it could be 1 or more bytes.
I cannot change the source of persist_result.
No C++; it must be a portable C solution.
What you are looking for is the Observer Pattern.
When your function is called, actually you can first capture that call, do whatever you prefer and then continue with what you were doing. You could implement it in C using pointer to functions.
You can get inspiration from the following example
There is no way to capture every operation in standard C without changing the calls. Things like encryption need context (like key) to work; that complicates life in general, but maybe persist_result() handles that automatically. How will you handle things like fseek() or rewind()?
I think you are in for a world of pain unless you write your I/O operations to a non-standard C API that allows you to do what's necessary cleanly. For example, your code might be written to call functions such as pr_fwrite(), pr_putc(), pr_fprintf(), pr_vfprintf(), pr_fseek(), pr_rewind(), etc — you probably wouldn't be applying this to either stdin or stdout — and have those do what's necessary.
If I were going to try this, I'd adopt prefixes (pr_ and PR) and create a header "prstdio.h" to be used in place of, or in addition to, <stdio.h>. It could contain (along with comments and header guards, etc):
#include <stdarg.h>
// No need for #include <stdio.h>
typedef struct PRFILE PRFILE;
extern PRFILE *pr_fopen(const char *name, const char *mode);
extern int pr_fclose(PRFILE *fp);
extern int pr_fputc(char c, PRFILE *fp);
extern size_t pr_fwrite(const void *buffer, size_t size, size_t number, PRFILE *fp);
extern int pr_fprintf(PRFILE *fp, char *fmt, ...);
extern int pr_vfprintf(PRFILE *fp, char *fmt, va_list args);
extern int pr_fseek(PRFILE *fp, long offset, int whence);
extern void pr_rewind(PRFILE *fp);
…
and all the existing I/O calls that need to work with the persist_result() function would be written to use the prstdio.h interface instead. In your implementation file, you actually define the structure struct PRFILE, which would include a FILE * member plus any other information you need. You then write those pr_* functions to do what's necessary, and your code that needs to persist results is changed to call the pr_* functions (and use the PRFILE * type) whenever you currently use the stdio.h functions.
This has the merit of being simply compliant with the C standard and can be made portable. Further, the changes to existing code that needs to use the 'persistent result' library are very systematic.
In a comment to the main question — originally responding to a now-deleted comment of mine (the contents of which are now in this answer) — the OP asked:
I need to do the encryption operation before the plain data write operation. The encryption context is ready for work. I was thinking using the disk on memory, but is it ISO and can be used in Android NDK and iOS too?
Your discussion so far is in terms of encrypting and writing the data. Don't forget the other half of the I/O equation — reading and decrypting the data. You'd need appropriate input functions in the header to be able to handle that. The pr_ungetc() function could cause some interesting discussions.
The scheme outlined here will be usable on other systems where you can write the C code. It doesn't rely on anything non-standard. This is a reasonable way of achieving data hiding in C. Only the implementation files for the prstdio library need know anything about the internals of the PRFILE structure.
Since 'disk in memory' is not part of standard C, any code using such a concept must be using non-standard C. You'd need to consider carefully what it means for portability, etc. Nevertheless, the external interface for the prstdio library could be much the same as described here, except that you might need one or more control functions to manipulate the placement of the data in memory. Or you might modify pr_fopen() to take extra arguments which control the memory management. That would be your decision. The general I/O interface need not change, though.

Is this a valid/good technique for avoiding global variables with C in embedded software?

I've looked long and hard into this topic of avoiding global variables and have come up with a way of doing it that I haven't really seen anywhere else in my searches which leads me to believe it's maybe not a great way of doing it (or I'm just not wording my search correctly).
As an example I have something like this:
int16_t DataProcessing(uint8_t CallType, struct DataStruct *DataIO)
{
int16_t RetVal;
static struct DataStruct StaticDataStuct;
switch (CallType)
{
case FIRSTCASE: RetVal = FirstCaseProcessing(&StaticDataStuct,DataIO); break;
case SECONDCASE: RetVal = SecondCaseProcessing(&StaticDataStuct,DataIO); break;
...
etc
...
}
return RetVal;
}
int16_t FirstCaseProcessing(struct DataStruct *StaticData, struct DataStruct *NewData)
{
// Do what you need to do here
}
Same idea for any other routines that are called.
I have also done wrapper functions to call DataProcessing() that makes the whole thing much easier to read and for new people using it in the future. So, for example:
int16_t FirstCase(uint8_t Address, uint16_t Data)
{
struct DataStruct NewData;
NewData.Address = Address;
NewData.Data= Data;
return DataProcessing(FIRSTCASE, &NewData);
}
So, what seems good, is that other than for the interrupts such as UART and timers, I have no global variables at all. (I still think getting in and out of interrupts as fast as possible is better than having an interrupt call something to store data in a static variable somewhere, but am happy to be persuaded otherwise.)
What is [maybe] bad is that I'm passing stuff through three functions in the interests of avoiding globals and making it more readable (assuming it's not just me that finds it readable!)
I would say that I have been given a 72MHz embedded 32 bit processor to do what could be done with an eight bit processor, running at a fraction of the speed (assuming it had enough RAM). So speed is not an issue, although I'm interested in opinions on whether this is a good style for when speed might be more of an issue.
I've seen the C++ style of having .c files and having static variables that any function within that .c file can see and access (but external files cannot), passing values/pointers etc in and out with accessor functions, but they seem to use what I would think are variables that are "global" to the file (or local to the file depending how you want to look at it!). Also, it's possible to have one function that stores a static variable and simply passes a pointer to that static variable to anything that wants to access it. I'm wondering whether that would be going OTT?
Does my idea seem good/bad/terrible?
Many thanks for any advice and all the TL;DRs I'm probably going to get. ;~)
OP:Does my idea seem good/bad/terrible?
Good OP is not yet OTT.
Avoiding global variables in embedded designs is a good goal primarily for the sake of maintenance. Information hiding (making data local to a function or object) is key to controlling the myriad of interactions and making debugging easier. This is especially true with OP faster (and likely larger memory) processor.
An alternative - hide data in file scope.
OP solution appears hierarchical as at DataProcessing(), command and Input/Output parameters are given and details of DataStruc are known at this level.
I'm aim for more of a data driven approach, using a pointer or index and a set of routines. Say in an embedded program I need, at most, Sally_N instances of a Sally variable. Here my data is not global, but hidden in the file scope of Sally.c. Thus the data and its detailed fields are hidden far from the higher level code that uses it. In OP's approach, the details of DataStruct are known to the higher level function DataProcessing().
// Sally.h
struct Sally_t; // Does not expose the fields
extern struct Sally_t *Sally_Init(...);
extern void Sally_DoThis(struct Sally_t *, ...);
extern void Sally_DoThat(struct Sally_t *, ...);
// Sally.c
struct Sally_t { int a, ... }; // Structure details
static struct Sally_t Sally_Data[Sally_N];// file scope prevents global exposure
struct Sally_t *Sally_Init(...);
void Sally_DoThis(struct Sally_t *, ...);
void Sally_DoThat(struct Sally_t *, ...);

C library naming conventions

Introduction
Hello folks, I recently learned to program in C! (This was a huge step for me, since C++ was the first language, I had contact with and scared me off for nearly 10 years.) Coming from a mostly OO background (Java + C#), this was a very nice paradigm shift.
I love C. It's such a beautiful language. What surprised me the most, is the high grade of modularity and code reusability C supports - of course it's not as high as in a OO-language, but still far beyond my expectations for an imperative language.
Question
How do I prevent naming conflicts between the client code and my C library code? In Java there are packages, in C# there are namespaces. Imagine I write a C library, which offers the operation "add". It is very likely, that the client already uses an operation called like that - what do I do?
I'm especially looking for a client friendly solution. For example, I wouldn't like to prefix all my api operations like "myuniquelibname_add" at all. What are the common solutions to this in the C world? Do you put all api operations in a struct, so the client can choose its own prefix?
I'm very looking forward to the insights I get through your answers!
EDIT (modified question)
Dear Answerers, thank You for Your answers! I now see, that prefixes are the only way to safely avoid naming conflicts. So, I would like to modifiy my question: What possibilities do I have, to let the client choose his own prefix?
The answer Unwind posted, is one way. It doesn't use prefixes in the normal sense, but one has to prefix every api call by "api->". What further solutions are there (like using a #define for example)?
EDIT 2 (status update)
It all boils down to one of two approaches:
Using a struct
Using #define (note: There are many ways, how one can use #define to achieve, what I desire)
I will not accept any answer, because I think that there is no correct answer. The solution one chooses rather depends on the particular case and one's own preferences. I, by myself, will try out all the approaches You mentioned to find out which suits me best in which situation. Feel free to post arguments for or against certain appraoches in the comments of the corresponding answers.
Finally, I would like to especially thank:
Unwind - for his sophisticated answer including a full implementation of the "struct-method"
Christoph - for his good answer and pointing me to Namespaces in C
All others - for Your great input
If someone finds it appropriate to close this question (as no further insights to expect), he/she should feel free to do so - I can not decide this, as I'm no C guru.
I'm no C guru, but from the libraries I have used, it is quite common to use a prefix to separate functions.
For example, SDL will use SDL, OpenGL will use gl, etc...
The struct way that Ken mentions would look something like this:
struct MyCoolApi
{
int (*add)(int x, int y);
};
MyCoolApi * my_cool_api_initialize(void);
Then clients would do:
#include <stdio.h>
#include <stdlib.h>
#include "mycoolapi.h"
int main(void)
{
struct MyCoolApi *api;
if((api = my_cool_api_initialize()) != NULL)
{
int sum = api->add(3, 39);
printf("The cool API considers 3 + 39 to be %d\n", sum);
}
return EXIT_SUCCESS;
}
This still has "namespace-issues"; the struct name (called the "struct tag") needs to be unique, and you can't declare nested structs that are useful by themselves. It works well for collecting functions though, and is a technique you see quite often in C.
UPDATE: Here's how the implementation side could look, this was requested in a comment:
#include "mycoolapi.h"
/* Note: This does **not** pollute the global namespace,
* since the function is static.
*/
static int add(int x, int y)
{
return x + y;
}
struct MyCoolApi * my_cool_api_initialize(void)
{
/* Since we don't need to do anything at initialize,
* just keep a const struct ready and return it.
*/
static const struct MyCoolApi the_api = {
add
};
return &the_api;
}
It's a shame you got scared off by C++, as it has namespaces to deal with precisely this problem. In C, you are pretty much limited to using prefixes - you certainly can't "put api operations in a struct".
Edit: In response to your second question regarding allowing users to specify their own prefix, I would avoid it like the plague. 99.9% of users will be happy with whatever prefix you provide (assuming it isn't too silly) and will be very UNHAPPY at the hoops (macros, structs, whatever) they will have to jump through to satisfy the remaining 0.1%.
As a library user, you can easily define your own shortened namespaces via the preprocessor; the result will look a bit strange, but it works:
#define ns(NAME) my_cool_namespace_ ## NAME
makes it possible to write
ns(foo)(42)
instead of
my_cool_namespace_foo(42)
As a library author, you can provide shortened names as desribed here.
If you follow unwinds's advice and create an API structure, you should make the function pointers compile-time constants to make inlinig possible, ie in your .h file, use the follwoing code:
// canonical name
extern int my_cool_api_add(int x, int y);
// API structure
struct my_cool_api
{
int (*add)(int x, int y);
};
typedef const struct my_cool_api *MyCoolApi;
// define in header to make inlining possible
static MyCoolApi my_cool_api_initialize(void)
{
static const struct my_cool_api the_api = { my_cool_api_add };
return &the_api;
}
Unfortunately, there's no sure way to avoid name clashes in C. Since it lacks namespaces, you're left with prefixing the names of global functions and variables. Most libraries pick some short and "unique" prefix (unique is in quotes for obvious reasons), and hope that no clashes occur.
One thing to note is that most of the code of a library can be statically declared - meaning that it won't clash with similarly named functions in other files. But exported functions indeed have to be carefully prefixed.
Since you are exposing functions with the same name client cannot include your library header files along with other header files which have name collision. In this case you add the following in the header file before the function prototype and this wouldn't effect client usage as well.
#define add myuniquelibname_add
Please note this is a quick fix solution and should be the last option.
For a really huge example of the struct method, take a look at the Linux kernel; 30-odd million lines of C in that style.
Prefixes are only choice on C level.
On some platforms (that support separate namespaces for linkers, like Windows, OS X and some commercial unices, but not Linux and FreeBSD) you can workaround conflicts by stuffing code in a library, and only export the symbols from the library you really need. (and e.g. aliasing in the importlib in case there are conflicts in exported symbols)

Resources