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:
- Include Guard
- 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!)