Tips/resources for structuring C code? [closed] - c

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
Does anyone have tips/resources for how to, in the best way, structure your C code projects? (Different folders etc.) And how do you know when it's good to split code into separate files? And what is an example of a good Makefile?
My project is not that big, but I wanna start to structure my code at an early stage..

Structuring code needs some experience but mostly common sense.
For splitting code, you usually go for readability: conceptually coherent functions/datatypes should go in the same file. You can take c standard library as a good example. It is better to keep your data structure definitions and function declarations in separate headers. This allows you to use the data structures as part of a compilation unit even if you have not defined all the functions.
Files that provide similar functionality should go in the same directory. It is good to avoid deep directory structure (1 level deep is best) as that complicates building the project unnecessarily.
I think Makefiles are OK for small projects, but become unwieldy for bigger ones. For really serious work (if you want to distribute your code, create an installer etc) you may want to look at cmake, scons, etc.
Have a look at the GNU coding standards: http://www.gnu.org/prep/standards/standards.html
Look at the gnu make manual for a simple example Makefile. You can also pick up any opensource project and look at the Makefile. Browsing code repositories in sourceforge.net may be useful.

Read one of the many C coding standards available on the internet and follow one that looks reasonable for your requirements. A few links:
GNU Coding Standards
C Coding Standards at IRAM (pdf)
Indian Hill C Style and Coding Standards
The following books also contain effective guidelines on writing good C code:
The C Programming Language
The Practice of Programming
The Elements of Programming Style

This is sometimes overlooked, but security is an issue in big projects. Here's some advice about how to program securely.

Here is an idiom I like:
Declare structs in a header so that their size is known by client code. Then declare init and deinit functions to the following convention:
The first parameter is a struct foo*.
The return type is a struct foo*.
If they might fail, the last parameter is either int* (simplest), enum foo_error* (if there are several ways it can fail that the calling code might care about) or GError** (if you're writing GLib-style code).
foo_init() and foo_deinit() return NULL if the first parameter is NULL. They also return the first parameter.
Why do it this way? Calling code doesn't have to allocate heap space for the structure, it can go on the stack. If you are allocating it on the heap, though, the following works nicely:
struct foo* a_foo = foo_init(malloc(sizeof(*a_foo)));
if (a_foo == NULL) {
/* Ruh-oh, allocation failure... */
}
free(foo_deinit(a_foo));
Everything works nicely even if a_foo == NULL when foo_deinit is called.

Related

Why does the standard C library feature multiple header files instead of consolidating the contents into a single header? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 months ago.
Improve this question
Why does the standard C library need to feature multiple header files? Would it not be more user friendly to consolidate it into one header file?
I understand that it is unnecessary to include function prototypes / global variables that go unused, however, won't the compiler eventually remove all of these references if they're unused?
Maybe I'm underestimating the size of contents spanning all of the header files. But it seems like I'm always googling to figure out what header I need to #include.
Edit: The top comment references a size of 50MB which appears to be untrue. The C library is relatively concise compared to other language's standard libraries hence the question.
// sarcasm ON
Build your own #include "monster.h" that includes all you want from the collection.
People write obfuscated code all the time. But, you won't be popular with your cohort.
// sarcasm OFF
The real reason? C was developed when storage was barely beyond punch card technology. A multi-user system might have 1/2Mb of (magnetic) core memory and a cycle time that is now laughable.
Yet, reams of C code was developed (and the story of the popularity of UNIX well known.)
Although new standards could change the details (and C++ has), there is an ocean of code that might/would no longer be able to be compiled.
Look up "Legacy".
There are (too many) examples of code in the world where the usual collection of, say, stdio.h, stdlib.h, etc. have been "hidden" inside #include "myApp.h". Doing so forces the reader to hunt-down a second file to verify what the &^%&%& is going on.
Get used to it. If it was a bad practice, it would not have survived for ~50 years.
EDIT: It is for a similar reason that "functions" have been "grouped together" into different libraries. By extension, pooling those libraries might make things a tiny bit "less cluttered", but the process of linking may require a supercomputer to finish the job before knock-off time.
EDIT2: Brace yourself. Cleanly written C++ code often has a .h and a .cpp for every class used in the app. Sometimes "families" (hierarchies) might live together in a single pair of files, although that can lead to boo-boo's when the coder is having a bad day...

Optimizing includes in C [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
My project has several header files. Most of C source files include all of those, so nearly every source file contains the following lines:
#include "add.h"
#include "sub.h"
#include "mul.h"
#include "div.h"
#include "conv.h"
#include "comp.h"
// etc.
Should this be moved to some all.h or similar? Is there a better way to do this?
In each .c file it should be easy to know what includes it needs. By doing your way, you could lose track of what includes it needs, and another colleague will need to look for this file.
In another words, you shouldn't do that because you lose clarity in your code.
There is also the third, somewhere-in-the-middle option, to have a minimum common.h for stuff which is shared by pretty much all your translation units (e.g. headers like stdint.h). Or perhaps you might decide to group add.h, sub.h and similar headers into a single ops.h header.
But having literally a single all.h header would make encapsulation/information hiding in C even harder than it is already. Does a math library in a spaceship microcontroller really need to know everything about life support systems?
Of course, C doesn't really have "first class encapsulation mechanisms", you can throw an extern function declaration pretty much everywhere, that's why it's rather important to stick to reasonable conventions and best practices.
There are pro and conses in both approaches (having one single all.h including all your headers, or not), so it is also a matter of opinion. And on a reasonably small project, having a single header file containing all your common declarations (and also definitions of static inline functions) is also possible.
See also this answer (which gives examples of both approaches).
A possible reason to have one single header (which includes other headers, even the system ones) is to enable pre-compilation of that header file. See this answer (and the links there).
A possible reason to favor several header files is readability and modularity. You might want to have one (rather small) header file per module and in every translation unit (practically every .c file) you would include only the minimal set of header files (in the good order).
Remember that C99 & C11 (and even C++14) do not have any notion of modules; in other words, modules in C are only a matter of conventions & habits. And conventions and habits are really important in C programs, so look at what other people are doing in existing free software projects (e.g. on github or sourceforge).
Notice that preprocessing is the first phase of most C compilers. Read documentation about your C preprocessor.
You practically would use a build automation system like GNU make. You may want to automatically generate dependencies (e.g. like here).
For a single-person project (of a few dozens of thousand source lines at most), I personally prefer to have a single header file, but that is a matter of opinion and taste (so a lot of people disagree). BTW, refactoring your project (to several header files) when it becomes large enough is quite easy to do (but harder to design); you'll just copy&paste some chunks of code in several new header files.
For a project involving several developers, you may want to favor the idea that most files (header or code) have one single developer responsible for them (with other developers making occasional changes to it).
Notice that header inclusion and preprocessing is a textual operation. You might in theory even avoid having header files and copy and paste the same declarations in your .c files but that is very bad practice so you should not do that (in hand-written code). However, some projects are generating C code (some sort of metaprogramming), and their C code generator (some script, or some tool like bison) could emit the same declarations in several files.

Is it wise to use the `this` keyword in C? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
Basically, I have a inline function in C:
struct array {
unsigned long size;
void* items;
};
typedef struct array* Array;
inline Array array_create(unsigned long initsize);
inline void array_free(Array this);
Am I free to use the this keyword in this kind of situation, or is it better to avoid it, and why (not)?
EDIT: This question originated from a bug in my code where I used inline void array_free(Array array); which changed the result of sizeof(array); and gave me the idea to use this instead of adapting to the (in my opinion ugly) sizeof(struct array);.
It's technically correct because C is not C++, so this is not a keyword in C.
Whether it's wise, now that's a different question. If there is any chance that this piece of code will ever be compiled as C++, then an identifier called this will break the code.
Using this in any fashion you want is totally valid C.
What you have to ask yourself, by the way these apply to any C++ reserved words like class, final etc, is :
Do I use a program that highlights this as a keyword conveing the wrong message ? e.g. Visual Studio highlights this even when you're in a .c file so some confusion may arise.
Do I plan to promote my code to C++ in the future ? In such a case you'll have some extra work to do that could be avoided.
Does my code interact with C++ ? This is not a problem per se but you have to bear in mind that your code will interact with C++ programmers as well. And you don't won't to confuse people that may not be aware of C in great detail (even though someone may say it's their duty do be aware of what they're doing when reading another language).
Since this is something that can be avoided I find using it immoral but not incorrect.
I'm not saying you have to study C++ prior to writing C, but once you know something, it's a good practice to make good use of it.
A subtle problem you may cause is to make your code 'uncallable' from C++ for example a
#define this some_definition
in a C header file that is later included from C++ may have weird effects to your code.
The reasons not to use this in standard C is that it makes your code:
Slightly less readable, due to the "well-known" usage of this in C++. Your code can look as if it's C++ and an uninformed reader can easily get confused.
Unportable to C++. If you (or someone else) ever want to take this code and use it in a C++ compilation, it will fail. That's a downside and an upside at the same time, since getting an error can be indicative that care must be taken, where's not getting one might let important issues slip.
It depends what your objective is.
If your C code program will always be built with a C compiler that is not a C++ compiler, then it makes no difference whether you use this as an identifier in your code. It is not a reserved identifier, so you are free to use it.
The potential problem with that premise is that a number of mainstream C compilers are actually C++ compilers, or they support some C++ features as extensions, so they may reject your code (or - less likely - do something with it that you don't expect). It is not possible to predict with absolute certainty that the vendor of your compiler(s) of choice will never (even if they give you a promise in writing) release a future version of their C compiler that will reject or do something unexpected with your code. The likelihood of this happening is relatively low, but non-zero.
In the end you need to decide what risk you are willing to take with maintaining your code in future.
Of course, if you are a C fanatic who wants your code to have an incompatibility with C++ (yes, such people do exist) then using a number of keywords or reserved identifiers that are specific to C++, as well as using such keywords or identifiers that are specific to (more recent versions of) C may be a worthwhile approach.
As it is already mentioned, you can use any non-reserved keyword as a variable name.
However, I suggest to use something like 'pThis', or '[struct name]This' or similar to express your intent of using a C struct together with functions that are taking as first argument a pointer to [struct name] instance, and are meant to be used in a similar manner as member functions of a C++ class.
This way your code may be more readable and your intent more understandable by someone who is using it.
In C you do not have the this keyword. Only in C++ and in a class, so your code is C and you use your this variable as a local method parameter, where you access the array struct.
Yes, you can. If the code happens to get compiled as C++, it is not your fault. However, in case that happens, other things won't be accepted; the fact that you likely assign to items without a cast, for instance, because C++ does not allow that unlike C.

Recommendations for 'C' Project Architecture Guidelines? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
Now that I got my head wrapped around the 'C' language to a point where I feel proficient enough to write clean code, I'd like to focus my attention on project architecture guidelines. I'm looking for a good resource that coves the following topics:
How to create an interface that promotes code maintainability and is extensible for future upgrades.
Library creation guidelines. Example, when should I consider using static vs dynamic libraries. How to properly design an ABI to cope with either one.
Header files: what to partition out and when. Examples on when to use 1:1 vs 1:many .h to .c
Anything you feel I missed but is important when attempting to architect a new C project.
Ideally, I'd like to see some example projects ranging from small to large and see how the architecture changes depending on project size, function or customer.
What resource(s) would you recommend for such topics?
Whenever I got serious writing C code, I had to emulate C++ features in it. The main stuff worth doing is:
Think of each module like a class. The functions you expose in the header are like public methods. Only put a function in the header if it part of the module's needed interface.
Avoid circular module dependencies. Module A and module B should not call each other. You can refactor something into a module C to avoid that.
Again, following the C++ pattern, if you have a module that can perform the same operations on different instances of data, have a create and delete function in your interface that will return a pointer to struct that is passed back to other functions. But for the sake of encapsulation, return a void pointer in the public interface and cast to your struct inside of the module.
Avoid module-scope variables--the previously described pattern will usually do what you need. But if you really need module-scope variables, group them under a struct stored in a single module-scope variable called "m" or something consistent. Then in your code whenever you see "m.variable" you will know at a glance it is one of the module-scope structs.
To avoid header trouble, put #ifndef MY_HEADER_H #define MY_HEADER_H declaration that protects against double including. The header .h file for your module, should only contain #includes needed FOR THAT HEADER FILE. The module .c file can have more includes needed for the compiling the module, but don't add those includes into the module header file. This will save you from a lot of namespace conflicts and order-of-include problems.
The truths about architecting systems are timeless, and they cross language boundaries. Here is a little advice focused on C:
Every module hides a secret. Build your system around interfaces that hide information from their clients. C's only type-safe information-hiding construct is the pointer to an incomplete structure. Learn it thoroughly and use it often.
One interface to an implementation is a good rule of thumb. (Interface is .h, implementation is .c.) Sometimes you will want to provide two interfaces that relate to the same implementation: one that hides the representation and one that exposes it.
You'll need naming conventions.
A superb model of how to handle these kinds of problems in C is Dave Hanson's C Interfaces and Implementations. In it you will get to see how to design good interfaces and implementations, and how one interface can build on another to form a coherent library. You will also get an excellent set of starter interfaces you can use in your own applications. For someone in your position, I cannot recommend this book too highly. It is an archetype of well-architected systems in C.
Namespace cleanliness - especially important with libraries. Prefix your public functions with the name of the library, in some fashion. If your library was called 'happyland', make functions such as "happyland_init" or even "hl_init".
This goes for the use of static. You will write functions which are specialized - hide them from other modules by using static liberally.
For libraries, reentrant is also critical. Do not depend on global state which is not compartmentalized (you can have a typedef struct token to keep this state if required).
Separate presentation code from logic. That is very important.
Static if they're used only in your project or in few binaries, dynamic when used many times (saves very much space).
Whenever code is used more than once, split it off into a header.
Those are a few of my known tips I can give you.
How to create an interface that
promotes code maintainability and is
extensible for future upgrades.
By exposing as few implementation details as possible. For example,
Use opaque pointers.
If you need a "private" function, declare it static, and don't put it in the .h file.

How should I structure complex projects in C? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I have little more than beginner-level C skills and would like to know if there are any de facto "standards" to structure a somewhat complex application in C. Even GUI based ones.
I have been always using the OO paradigm in Java and PHP and now that I want to learn C I'm afraid that I might structure my applications in the wrong way. I'm at a loss on which guidelines to follow to have modularity, decoupling and dryness with a procedural language.
Do you have any readings to suggest? I couldn't find any application framework for C, even if I don't use frameworks I've always found nice ideas by browsing their code.
The key is modularity. This is easier to design, implement, compile and maintain.
Identify modules in your app, like classes in an OO app.
Separate interface and implementation for each module, put in interface only what is needed by other modules. Remember that there is no namespace in C, so you have to make everything in your interfaces unique (e.g., with a prefix).
Hide global variables in implementation and use accessor functions for read/write.
Don't think in terms of inheritance, but in terms of composition. As a general rule, don't try to mimic C++ in C, this would be very difficult to read and maintain.
If you have time for learning, take a look at how an Ada app is structured, with its mandatory package (module interface) and package body (module implementation).
This is for coding.
For maintaining (remember that you code once, but you maintain several times) I suggest to document your code; Doxygen is a nice choice for me. I suggest also to build a strong regression test suite, which allows you to refactor.
It's a common misconception that OO techniques can't be applied in C. Most can -- it's just that they are slightly more unwieldy than in languages with syntax dedicated to the job.
One of the foundations of robust system design is the encapsulation of an implementation behind an interface. FILE* and the functions that work with it (fopen(), fread() etc.) is a good example of how encapsulation can be applied in C to establish interfaces. (Of course, since C lacks access specifiers you can't enforce that no-one peeks inside a struct FILE, but only a masochist would do so.)
If necessary, polymorphic behaviour can be had in C using tables of function pointers. Yes, the syntax is ugly but the effect is the same as virtual functions:
struct IAnimal {
int (*eat)(int food);
int (*sleep)(int secs);
};
/* "Subclass"/"implement" IAnimal, relying on C's guaranteed equivalence
* of memory layouts */
struct Cat {
struct IAnimal _base;
int (*meow)(void);
};
int cat_eat(int food) { ... }
int cat_sleep(int secs) { ... }
int cat_meow(void) { ... }
/* "Constructor" */
struct Cat* CreateACat(void) {
struct Cat* x = (struct Cat*) malloc(sizeof (struct Cat));
x->_base.eat = cat_eat;
x->_base.sleep = cat_sleep;
x->meow = cat_meow;
return x;
}
struct IAnimal* pa = CreateACat();
pa->eat(42); /* Calls cat_eat() */
((struct Cat*) pa)->meow(); /* "Downcast" */
All good answers.
I would only add "minimize data structure". This might even be easier in C, because if C++ is "C with classes", OOP is trying to encourage you to take every noun / verb in your head and turn it into a class / method. That can be very wasteful.
For example, suppose you have an array of temperature readings at points in time, and you want to display them as a line-chart in Windows. Windows has a PAINT message, and when you receive it, you can loop through the array doing LineTo functions, scaling the data as you go to convert it to pixel coordinates.
What I have seen entirely too many times is, since the chart consists of points and lines, people will build up a data structure consisting of point objects and line objects, each capable of DrawMyself, and then make that persistent, on the theory that that is somehow "more efficient", or that they might, just maybe, have to be able to mouse over parts of the chart and display the data numerically, so they build methods into the objects to deal with that, and that, of course, involves creating and deleting even more objects.
So you end up with a huge amount of code that is oh-so-readable and merely spends 90% of it's time managing objects.
All of this gets done in the name of "good programming practice" and "efficiency".
At least in C the simple, efficient way will be more obvious, and the temptation to build pyramids less strong.
The GNU coding standards have evolved over a couple of decades. It'd be a good idea to read them, even if you don't follow them to the letter. Thinking about the points raised in them gives you a firmer basis on how to structure your own code.
If you know how to structure your code in Java or C++, then you can follow the same principles with C code. The only difference is that you don't have the compiler at your side and you need to do everything extra carefully manually.
Since there are no packages and classes, you need to start by carefully designing your modules. The most common approach is to create a separate source folder for each module. You need to rely on naming conventions for differentiating code between different modules. For example prefix all functions with the name of the module.
You can't have classes with C, but you can easily implement "Abstract Data Types". You create a .C and .H file for every abstract data type. If you prefer you can have two header files, one public and one private. The idea is that all structures, constants and functions that need to be exported go to the public header file.
Your tools are also very important. A useful tool for C is lint, which can help you find bad smells in your code. Another tool you can use is Doxygen, which can help you generate documentation.
Encapsulation is always key to a successful development, regardless of the development language.
A trick I've used to help encapsulate "private" methods in C is to not include their prototypes in the ".h" file.
I'd suggets you to check out the code of any popular open source C project, like... hmm... Linux kernel, or Git; and see how they organize it.
The number rule for complex application: it should be easy to read.
To make complex application simplier, I employ Divide and conquer.
I would suggest reading a C/C++ textbook as a first step. For example, C Primer Plus is a good reference. Looking through the examples would give you and idea on how to map your java OO to a more procedural language like C.

Resources