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.
How should I structure these projects in Git?
I have a template written in TeX from which I start most of the documents I write, consisting of a few .tex files and some other auxiliary files too. I’d like this template and any downstream document
How should I test a complex method?
I have a complex method I want to test, It recieves user, UserUpdatedDetails(password, restore question and email) and password. And it should check the following: Make sure user updated all fields t
how should I structure data for a complex object in ActionScript 3?
I hope this isn’t too vague, but I’m stuck on a problem that has put me in an Unfortunate Position. I’m Flash developer getting my feet wet with with AS3 and am trying to build an interior decoration
How to construct and manage this complex C data structure?
I’m quite confusing how to efficiently manage (populating and accessing) the following data structure in C. To describe in brief, I have a struct that contains a member of another struct, and that str
How should I structure this loop?
From time to time, I run into loops like this one, where I’m not sure how it should be structure to both avoid code repetition and make it most readable. Please note that while in this example I write
How to structure dependent projects on github?
I recently put some of my projects on github to make them open source but I’m having trouble understanding how to structure the projects properly. I’ve got a Core project and another project that depe
How should I implement complex business logic?
I have a scenario where I am processing a queue of MailItems. Once I have processed each MailItem, I need to update the Status of the MailItem. The logic for updating the status is quite complex. My t
How complex should models be?
When implementing models using the MVC pattern, how complex should my models be? Let’s say I have got a few tables like so: User (id, password, created …) Emails(user_id, email …) Addresses (user
Should I create one complex RegEx or multiple and less complex ones?
Should I create one complex RegEx to tackle all cases on hand or should I break one complex RegEx in multiple Regex which ? I’m concerned regarding performance using complex Regex. Will breaking the c
How should I manage dependencies in C or C++ open source projects?
I’ve got a few open source applications. These depend on a few third party components, notably Crypto++ and Boost. There are a couple of options to take: Put third party code into version control, an
Answers
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.
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.
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.
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 = (Cat*) malloc(sizeof (struct Cat)); x->_base.eat = cat_eat; x->_base.sleep = cat_sleep; x->meow = cat_meow; } struct IAnimal* pa = CreateACat(); pa->eat(42); /* Calls cat_eat() */ ((struct Cat*) pa)->meow(); /* "Downcast" */
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.
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.
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.
The Unix philosophy is pretty useful for organizing large projects: