views:

806

answers:

5

Can you recommend me what should I read/learn in order to make a well organized code in C?

One of the things I want to learn is the principles of splitting project in .h and .c files, what goes where and why, variable naming, when to use global variables ...

I am interested in books and articles that deal with this specific problem.

+1  A: 

I think the best educational reading you're going to get on this subject, is reading something like the Linux Kernel source. It's got a good source layout, and is basically the standard large C project. Here is a guide for how source files should be put together for BSD source, as well.

Seriously, just start reading Kernel source and get a feel for how everything is put together. It's a very well planned project, obviously.

Alex Fort
+4  A: 

A good book that covers a lot of this (for both C and C++) is Large Scale C++ Software Design, by John Lakos:

Also, a good rule of thumb to remember is "Never do anything that allocates memory in a header file"

George Sealy
"Never do anything that allocates memory in a header file"---I like that. Succinct and a pearl of wisdom.
dmckee
@George Sealy: just to make sure that I get that right, allocating memory in a header file is a problem because if two .c files include it, there will be linker ambiguities. Am I correct?
Lazer
Just wondering, could you elaborate on that rule of thumb? I can understand if its static allocation (e.g. a variable without an `extern` in front of it), but I don't really see how it's a problem, say, with `malloc`.
Edmund
@Lazer - yep@Edmund - Another way of looking at what I'm saying is declare things in .h files, don't define them. If you have a variable that's being initialized and malloc'ed in a header file, you're asking for potential trouble.
George Sealy
+2  A: 

Specific to unix (and not to c, natch), but none the less:

Recursive Make Considered Harmful

With the build structure described, you can afford to use a lot of files. So each logical unit gets a header and a source file.

dmckee
+1  A: 

Read:

Organizing Code Files in C and C++.

It is very well written.

Lazer
A: 

Regarding the files layout there are not too many alternatives.

The partitioning is typically one of the following (package here is a single library or binary):

  1. .../project/.../package/module.{c,h}
  2. .../project/.../{src,include}/package/module.{c,h} // non-interface headers go to src
  3. .../project/.../package/{src,include}/module.{c,h} // non-interface headers go to src

The partitioning (1) is convenient in that all files belonging to particular package are stored in a single directory, so package can be easily moved around, but with this approach detaching API headers from private ones and detecting API changes is not trivial. (2) and (3) are very similar, they make API release and API changes detection trivial, while (2) is slightly easier for the case when you always release the whole project and (3) is slightly better when you release individial packages (e.g. for patching purposes)

In any C/C++ project there is typically the following common packages:

  1. Common macros, and data types
  2. Logging package
  3. Application bootstrap package (in case there are more than 1 binaries in the project).
bobah