9

I have been learning C for a while but still get confused about designing large programs within C (a large application such as the Linux kernel).

Moving from Java where you have classes it's difficult to understand how to design a large application in C.

What advice/links can people advise from moving from a high level language to designing applications in a low level language such as C?

6
  • um...don't? I'm kidding...kind of - you can make classes in C. Do google for OOP in C. Commented May 14, 2012 at 22:47
  • 1
    The first question is: why? Unless a higher level language isn't available on the platform (and it's hard to imagine a platform without C++ these days) I can't imagine why you'd want to do this. (Speaking as someone who designed large scale applications in C back when that was the only choice.)
    – user53141
    Commented May 14, 2012 at 23:39
  • 1
    @StevenBurnap For fun and as a challenge. I was challenged at the pub to write our Java Assignment in C. So I thought why not as a learning exercise. And then I began to start thinking about the design of large applications in C.
    – Dean
    Commented May 14, 2012 at 23:57
  • Are you most interested in doing a large C project like a C programmer would, or do you want to try to do OO in C? Both are interesting exercises. Going from Java to C, the biggest issue you are going to have is the complete lack of collection classes in C. (Though third party libraries are available.)
    – user53141
    Commented May 15, 2012 at 0:14
  • Yes, just generally developing a large C project, I'm not interested in porting exactly my java assignment. I'd just like experience with working on large applications so I can understand how they are designed and implemented.
    – Dean
    Commented May 15, 2012 at 0:16

2 Answers 2

7

In general, the lower level the language, the more rigorous you have to be about style. Many of the same style rules to any language are important. Keep functions short. Keep like methods together. Generalize repeated code. Also, lower level code demands more comments as the code is itself less readable.

In most cases, the methods you'd use to keep things organized are more verbose and more manual. Basically, in C, you get something like encapsulation by keeping related functions in a single source file and using static globals for any data they need to share. You can use this to simulate private data in a class. Or more correctly, this creates something like a "Module", which was the structured programming world's answer to large scale program development before OO came along.

In a similar manner, you can use the same handle method used by system libraries like fopen to create something like a class. Internally you have a table that maps handles to the "instance data". Or you can also pass a raw pointer back and forth.

In general, try to be as "functional" as you can. Avoid globals and side effects and do as much communication as you can with parameter passing.

One big problem is that you have no help with memory management, so you need to be very rigorous about when you allocate and free memory. Allocated data that goes together should be tied together somehow so that it can all be freed in a single destroy function. Try to have a general structure to when things are allocated and freed. Also, allocate on the stack whenever you possibly can. One big help is the new dynamic arrays in C99.

The other big problem is the complete lack of collection classes. Best way to solve this is to go looking for third party solutions. You don't want to spend all of your time debugging custom hash table implementations.

You can go all out and fully implement OO by doing by hand what C++ compilers do for you. Make classes by creating structs with function pointers for virtual methods. You can use the same hack C++ does to derive classes by having the "child" class have function pointers to the base class methods in the same order in memory. This is a bad idea for a real program, but can be an interesting learning exercise.

1
  • All sound advice. Governance is really the key with enforcing encapsulation and information hiding. I worked on a very successful project in C that totaled ~1M loc at the time. Creating such a project can most definitely be done and still be maintainable.
    – user53019
    Commented May 15, 2012 at 17:13
2

You wind up implementing objects more directly, without the syntactic sugar. Essentially, structs with function pointers.

You mention the Linux Kernel; you might consider reading its source looking for that pattern.

4
  • Yes i mention the Linux kernel because its the largest thing I know written in C and is an example of an open source project.
    – Dean
    Commented May 14, 2012 at 22:37
  • 1
    Sort of like how buying lumber at a lumber yard rather than harvesting and milling your own trees is "dimensional sugar". Commented May 14, 2012 at 22:50
  • And of course the extreme case is to write a programming language in C, and then implement your large application in that language. Though you might call it a "DSL"... ;)
    – retracile
    Commented May 15, 2012 at 15:30
  • As for the Linux kernel, the driver code uses structs with function pointers, as do a number of other areas. Once you've seen the pattern, you should be able to find more examples in the kernel sources.
    – retracile
    Commented May 15, 2012 at 15:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.