www.digitalmars.com Home | Search | CTG | RTL | IDDE | STL
Last update Sat Apr 8 23:54:06 2006
Compiler & Tools Guide

Compiling
Compiling Code
C Implementation
C++ Implementation
Language Extensions
Mixing Languages
Assembly Language
Inline Assembler
Optimizing Code
Numerics Programming
Regular Expressions
Acrtused
Pragmas
Precompiled Headers
Predefined Macros
Warning Messages
Error Messages
Runtime Messages


Linking
Optlink
Switches
Module Definition Files
Operation and Design
Error Messages


Win32 Programming
Win32 Programming


DOS and Win16
Programming

Memory Models
16 Bit Pointer Types
and Type Modifiers

Handle Pointers
DOS
DOS 32 (DOSX)
Win16
Win16 DLLs
Win16 Prolog/Epilog


C/C++ Extensions
Contract Programming
__debug statement
__debug declaration
Dynamic Profiling
Embedding C in HTML


Tools
BCC
CHMOD
CL
COFF2OMF
COFFIMPLIB
DMC
DIFF
DIFFDIR
DUMP
DUMPOBJ
DUMPEXE
EXE2BIN
FLPYIMG
GREP
HC
IMPLIB
LIB
LIBUNRES
MAKE
MAKEDEP
ME
OBJ2ASM
PATCHOBJ
RC
RCC
SC
SHELL
SMAKE
TOUCH
UNMANGLE
WHEREIS


Porting to DMC++
Switching to DMC++
from Microsoft
from Borland
Porting Guide


Precompiled Headers

If your program uses a large header file or numerous small headers, the compiler spends considerable time compiling the same code over and over again. To save compile time, precompile a header file; the compiler can load a precompiled header faster than it can a text header file. The compiler includes a precompiled header only once in a file, regardless of how many #include statements for it appear.

How the compiler precompiles a header

A precompiled header consists of the header file's global symbol table and any macros defined by the header. A header intended for precompilation should, therefore, contain only declarations and no definitions.

For example, the following declarations are appropriate for use in precompiled headers:

	extern int abc;
	int foo(int x); 
	inline void g(x) { foo(x); } // inline function definition 
	#define MACRO(x) asdf(x) 
These will not work:
	int def = 3; // a definition
	void g(x) { foo(x); } // function definition 

Precompiled header options

These switches to SC control precompiled headers. Corresponding IDDE options are in the Header Files subpage on the Build page of the IDDE's Project Settings dialog box.
  • -H Use precompiled headers
  • -HC Do not cache precompiled headers in memory
  • -HDdirectory Read/write precompiled headers in directory
  • -HF[filename[.sym]] Write precompiled header to filename.sym
  • -HI Include header file
  • -HMaddress Set address for memory mapped files precompiled header files
  • -HO Include header files only once
  • -HS Search for include files only in -Ipath directories
  • -HX Use automatic precompiled headers
  • -Ipath Set search path for include files
To use a precompiled header:
  • Create a directory for the program files.
  • #include the header file in each source file.
  • Edit the program's makefile.
Create a directory specifically for the program that includes its source files and makefile. When compiling, this directory is the current directory, and the compiler automatically writes the precompiled headers there. A program should have its own directory because precompiled headers are highly specialized, and it is unlikely that a precompiled header for one program can work with another.

#include the precompiled header in the source as you normally would. For example, to use a precompiled version of stdio.h in a program, write:

	#include <stdio.h> 
	main()
	{ 
	    printf("hello world\n");
	} 
The program's makefile must precompile the header file and include the precompiled header in the list of dependencies for all the source files that #include it. For example, this is the makefile for the hello world program:
	stdio.sym : stdio.h makefile
		sc -HF stdio.h 

	hello.exe : hello.c stdio.sym
		sc -H hello 
The first two lines are for the precompiled header. The name of the precompiled header is the same as the text header, except it ends in .sym instead of .h. The sc -HF command precompiles the header file, creates a .sym file and places it in the current directory. The precompiled header depends not only on the text header file, but also on the program's makefile. This is because changes in the makefile, such as using a different memory model or target CPU, change how the compiler precompiles the header.

The last two lines above are for the program's source file. The executable file is dependent not only on its source file, but also on the precompiled header. The -H option tells the compiler that when it looks for a header file, it should first look in the current directory for .sym files.

Using a project precompiled header

If many source files #include the same files, you might want to create a project precompiled header that #includes several text header files.

For example, if the files in the project all #include stdio.h, string.h and myglobals.h, create a project header file project.h that contains just these lines:

	#include <stdio.h>
	#include <string.h> 
	#include "myglobals.h" 
Precompile project.h with this command:
	sc -HF project.h 
Then compile them with the -H and -HI options:
	sc file1 file2 file3 -HIproject.h -H 

"Automatic" Precompiled Headers (-HX)

Using -HX improves compile times for most programs. Instances where this might not be the case include:
  • When the file being compiled causes scph.sym to be regenerated but that contains a subset of the #include files as do other files in the program.
  • When #include files are nested in #if or extern "C" { } blocks. Fix by putting the extern "C" statements in the #include files themselves.

Using a fast disk with a precompiled header

To make a precompiled header file even faster, place it on the fastest disk drive in your system. To let the compiler know where the precompiled file is, make some changes in the makefile. First, precompile the header file with -HF to specify where to place it. Then, use -HD to set the path to read the precompiled header.

For example, if the fastest disk is drive e, the makefile for the hello world program would be:

	TMP=e: 

	stdio.sym : stdio.h makefile
		sc -HF stdio stdio.h 

	hello.exe : hello.c stdio.sym
		sc -HD hello 
or, with automatic precompiled headers:
	TMP=e: 

	hello.exe : hello.c
		sc -HD -HX hello 

Tips For Precompiled Headers

To make the best use of precompiled headers, follow these rules:
  1. Header files should contain complete definitions, i.e. starting a declaration in one file and finishing it in another should be avoided. Every header file should be self-contained.
  2. Design headers so they only need to be #include'd once. Then, wrap the header in:
    	#ifndef _HEADER_H
    	#define _HEADER_H 1
    		... declarations ...
    	#endif // _HEADER_H
    	
    so that if it is #include'd multiple times, it is parsed only once. In addition, add:
    	#pragma once
    	
    to it so the compiler doesn't need to rescan it.
  3. Design headers so they can be #include'd in any order. The best way to do this is to have each header #include the ones it depends on. By following rule (2), this will not have a compile time penalty.
  4. Avoid defining data in the headers.
  5. Avoid putting executable code, other than inline functions, in headers.
  6. Avoid #undef'ing macros and redefining them to something else.
  7. If the struct packing is set to something other than the default, set it back to the default before the end of the file.
  8. Do not write extern "C" constructs that start in one file and end in another.
  9. If the header file has changed since the last time you precompiled it, the compiler uses the older precompiled header file. Updating the precompiled header file should be done by the makefile.
  10. #include directives for precompiled header file(s) should be the first line(s) in a source file other than comments. If other code precedes the #include directive for a precompiled header, ensure that the code does not affect compilation of the header file.