Take the 2-minute tour ×

Although I am not an experienced programmer in C, I have to use this language at work to build a static library which compiles both on SunOS and Win32. This library has just a few source files and their correspondent headers (let's say: a.c, b.c, a.h and b.h). The project compiles in both platforms and the library mylib.a is generated.

My problem is how to expose the implemented functions of mylib.a to other projects, because when I add both a.h and b.h I get some macro redefinition errors.

EDIT: I found that the macro redefinition error was because of a macro definition into the compilation command (not related to my headers) and it is solved :) But still I would like advice on organizing my source and header files.

My doubt is whether I modify a.h and b.h to be used externally or if I should create a header file specifically for declaring the interface of this library (let's say mylib.h). I would not like to overcomplicate the original headers, but I would not like to have to keep a different header in sync ... I would like to hear from more experienced C programmers about their patterns, advantages of each approach and whether there are other options.

Thank you in advance.

EDIT: seems I have not provided enough information; the schema below tries to show how my files are organised: each code file only includes its header, each header has a guard condition, each header includes a common header, this common header includes all headers.

// a.c ----
#include "a.h"

// b.c ----
#include "b.h"

// a.h ----
#ifndef GUARD_A_H
#define GUARD_A_H
  # include "liball.h"
  void function_prototypes_implemented_in_a();
#endif // GUARD_A_H

// b.h ----
#ifndef GUARD_B_H
#define GUARD_B_H
  # include "liball.h"
  void function_prototypes_implemented_in_b();
#endif // GUARD_B_H

// liball.h ----
  # include <time.h>   // standard headers
  # include <stdioa.h>

  # include "a.h"      // all headers in this project
  # include "b.h"
#endif // GUARD_LIBALL_H
share|improve this question
Can you show us the errors and relevant code ? also do you use header guards ? –  mux Nov 6 '12 at 11:28
"when I add both a.h and b.h I get some macro redefinition errors"? Definitely just keep the 2 separate header files, and fix them. Each header file should be usable separately or together with any other header files, so you need to give your macros better names, e.g. by prepending some letters to the front that indicate the "namespace" (neither C macros nor C identifiers in general have namespaces, so this is the best you can do). –  j_random_hacker Nov 6 '12 at 11:33
It's common to have one or more public header files to be used by others using your library. Sometimes they are used stand-alone, sometimes they include private files. –  Joachim Pileborg Nov 6 '12 at 11:35
And yes, it's a good idea to make a 3rd header that simply #includes the other two headers to simplify usage for users of the library. –  j_random_hacker Nov 6 '12 at 11:51
That pattern is fine - it organises the files neatly, and minimizes the number of #include directives you have to have - but it does mean that every .c file depends on every .h file which means incremental rebuilds are more expensive. That's not a huge issue for most projects though, and has zero impact on a build from clean, so feel free to do that, if you wish. –  ams Nov 6 '12 at 13:06
show 4 more comments

2 Answers

up vote 3 down vote accepted

You should have a public header, mylib.h, that only contains the definitions a user of the library needs to know.

You then have a private header, mylib-internal.h, that is used within your project. You should not try to keep the two "in sync", but rather have mylib-internal.h contain #include "mylib.h".

You should also name all your interface functions like mylib_initialize() etc., and ensure that all private, internal functions are either declared static, or else named _mylib_internal_whatever(), so that users don't get namespace clashes with other libraries.

share|improve this answer
Nice point, @ams, but shouldn't functions implemented in a.c have their prototypes declared into a.h? Is this a bad practice? –  Gerardo Lima Nov 6 '12 at 11:55
@GerardoLima Yes, that's the best practice within a project: it minimizes the amount of .c files you have to rebuild every time you modify a header file. But mylib.h is for users and corresponds 1-to-1 with libmylib.a, so that's more important. Duplication between header files is a maintenance problem, so if you're doing that you may be Doing It Wrong. –  ams Nov 6 '12 at 12:39
Sorry, @ams, but still it is not clear to me. I liked your suggestion of creating an internal.h which imports the external.h, but should I declare all prototypes within these files or should I keep them into a.h and b.h and import those into external.h? This can be very tricky, I have over 10 years experience programming, but these subtleties of C sometimes make me look like a fool. –  Gerardo Lima Nov 6 '12 at 12:55
You should have one declaration for each function, type, and macro. Duplication causes bugs, so don't do it. You should hide the definitions of anything a user of the library doesn't need to know, so don't put them in the external mylib.h, but you can put them wherever you choose: the source is yours. (If you expose internal details then some idiot user will rely on them and then you'll never be able to change them without breaking his app.) –  ams Nov 6 '12 at 13:01
add comment

You're question is too vague so my answer is a generic advice, you should avoid double inclusion and use include guards in the headers, like so:


#ifndef __HEADER_A_H__
#define __HEADER_A_H__ 


#ifndef __HEADER_B_H__
#define __HEADER_B_H__ 

Edit: Like I said, avoid double (or circular) inclusion there's no need for liball.h to include a.h and b.h also, note that liball.h header guard is same as b.h, so b.h will not be defined at all !

share|improve this answer
I already use guards, @mux. They work fine into the project that builds the library itself, but apparently they aren't preventing these erros. –  Gerardo Lima Nov 6 '12 at 12:02
I added some more information about how my source is organized, maybe it can help find the cause of the problem. –  Gerardo Lima Nov 6 '12 at 12:02
@GerardoLima check edit –  mux Nov 6 '12 at 12:16
the problem with the liball guard does not exist in my project (it was a quick edit misspell, and it is corrected now). The reason I include a.h and b.h into liball.h is because some functions of a are used in b and likewise -- actually, there are 5 source (C) files. –  Gerardo Lima Nov 6 '12 at 12:22
add comment

Your Answer


