Important Header Features

Up to this point, all the awesome library’s header file has are the forward declarations for the library’s functions:

/*
awesome.h
Header file for the awesome library.
*/

#include "simpletools.h"                      // Include simple tools

int awesome_getCount(void);  
void awesome(void);
void epic(void);
int awesome_startTimer(void);                 
void awesome_stopTimer(void);                 
int awesome_secondsSince(void);              
int awesome_secondsReset(void);   

We can add two more features to make our library robust:

  1. Include Guard
  2. C++ compatibility block

 

The Include Guard

An include guard prevents compiler errors that could result if two different parts of an application #include the same header file.  Without a guard, the C preprocessor could end up trying to process the header twice if two different libraries #include it.  With a guard, the C preprocessor keeps the information from the header with the first #include, and skips it the second time because it sees the guard.

An include guard looks like this:

#ifndef UNIQUE_NAME_FOR_HEADER_FILE           // Include guard
#define UNIQUE_NAME_FOR_HEADER_FILE

...All header file declarations...

#endif                                        // End Include guard

/* UNIQUE_NAME_FOR_HEADER_FILE */ 

The first lines say "if the UNIQUE_NAME_FOR_HEADER_FILE macro name has not already been defined, keep going, otherwise, skip everything until #endif is reached."

The first time the preprocessor goes through the header it will process all the information.  Since one of the items in there is #define UNIQUE_NAME_FOR_HEADER_FILE, that macro name will be defined.  So the second time it tries to process that header, it’ll see the #ifdef, realize that UNIQUE_NAME_FOR_HEADER_FILE is already defined and skip it.

 

The C++ Compatibility Block

The header information should also be placed inside a block of code that allows it to be used by a C++ compiler.  A C++ compiler updates function names with some additional information to support a C++ feature called overloading, but this can cause compiler errors when used on C code.  The compatibity block code tells a C++ compiler to just compile the function names with C instead of C++.

#if defined(__cplusplus)                      // If compiling for C++
extern "C" {                                  // Compile for C
#endif

...All header file declarations...

#if defined(__cplusplus)                     
}                                             // End compile for C block
#endif
/* __cplusplus */  

If SimpleIDE’s compiler is set to C++ in the project settings, __cplusplus will automatically get defined.  In that case, #if defined(__cplusplus) will add extern “C” { above the header info and } below it, so that it gets compiled without the extra overloading information and the compiler errors that would cause.

 

Add Features to awesome.h

Let’s apply the include guard and C++ compatibility block to awesome.h.

  • Update awesome.h as shown below.
  • Leave the Compiler Type set to C, not C++
  • Recompile for the memory models you plan to use (CMM, LMM, etc.).
/*
awesome.h

Header file for the awesome library.
*/

#ifndef AWESOME_H                             // Prevents duplicate
#define AWESOME_H                             // declarations

#if defined(__cplusplus)                      // If compiling for C++
extern "C" {                                  // Compile for C
#endif

#include "simpletools.h"                      // Requires simpletools

void awesome(void);                           // Forward declarations
int  awesome_getCount(void);
int  awesome_startTimer(void);
void awesome_stopTimer(void);
int  awesome_secondsSince(void);
int  awesome_secondsReset(void);
void epic(void);

#if defined(__cplusplus)                     
}                                             // End compile for C block
#endif
/* __cplusplus */

#endif                                        // End prevent duplicate forward
/* AWESOME_H */                               // declarations block    

Congratulations!  Now there's only one thing left to do: optionally document your library to make it easier for other people to use (and easier for you to remember what you did!)