Recall: The preprocessor transforms your program before the compiler sees it
include is a preprocessor directive
This sets a preprocessor variable to have value, all occurrences of VAR in your source file get replaced with VAL except occurrences in quoted strings.
However, this is not used a lot in C++, in fact, almost never used. It is ALWAYS better to just use const.
This sets the variable FLAG, its value is the empty string
Defined constants are useful for conditional compilation
What this means is hiding code from the complier that you don’t necessarily want compiled
For example:
Special case:
\#if 0 is never true, so all of the inner text is removed before the compiler sees it, works as a heavy duty “comment out”.
We can also define preprocessor symbols, via the command-line compiler arguments.
Say we have the following incorrect code:
Then, to compile it, we:
x is now set to 15 through the command-line.
\#ifdef
NAME/\#ifdef NAME, true if var/flag has/has not been defined.
Compiling this: g++ loop.cc -o loop, we see no print statements
Now, with:
With the above, we see our prints.
Separate compilation
The point of this is to split the program into composable modules, each which provide:
Interface file:
type definitions
prototypes (declarations)
This is the header file, the .h file
Implementation:
Full definition for every provided function
The .cc file
Recall from C
declaration: asserts existence
definition: full details, allocates space ( for var and functions)
Example
Compiling Separately
NEVER COMPILE**.h files**
To do so, we use;
What happens if we change vec.cc, we only need to recompile vec.cc and relink
But, what if we change vec.h? Now, we need to recompile vec.cc and main.cc since both files include vec.h, and then we must relink.
How can we keep track of dependencies, and perform minimal compilation?
Linux tool: make
To use make, we create a makefile (must be named that), that says which files depend on which other files, and how to build your program.
Then from cmd-line:
make just checks time stamps, if a target is older than its dependencies, it must rebuild (can cascade.recurse)
lets generalize with variables
Great, but the biggest problem is knowing dependencies
We can get help from g++ with the -MMDflag, which produces compilation dictionaries
now,:
As project expands, only have to add .o filesto the OBJECTS variable.