@import directive

The xcpp preprocessor copies C/C++ preprocessor commands such as #pragma, #include and #define verbatim from input to output. In all other respects it ignores these directives (and trusts their processing to the standard C/C++ compiler).

To make the xcpp preprocessor process and access the directives from another file, a @import directive must be used. This is essentially the same as C/C++ #include, and takes the path to a file to be included at that location in double quotes. In fact an import directive is translated to a corresponding #include directive by the xcpp preprocessor in preparation for a standard C/C++ compiler. For example:

Before translationAfter translation
#include "blah.h"
@import "mydir/myfile.h"
int f() { return 1; }
#include "blah.h"
#include "mydir/myfile.h"
int f() { return 1; }

There is a crucial conceptual distinction between a #include and a @import. A #include indicates that the contents of the file are to be inserted at that location and processed in that context. In C/C++ the processing of the file could be influenced by earlier #define directives. For example, consider a header file:


#ifdef X
typedef int Y;
#else
typedef double Y;
#endif

The processing of this file is influenced by whether a #define X directive appears before it. Some programmers exploit this capability - by including the same file from different places, causing it to generate variable output.

This practice is rejected in the xcpp preprocessor because its macro expansion capabilities are easily powerful enough to eliminate the need for such techniques, and assuming every file has a consistent translation allows the preprocessor to cache the namespace of macro definitions obtained by processing the file. This allows for significant performance gains in the xcpp preprocessor for large projects.

The word import is intended to indicate that the directive causes the importing of one namespace into another. The implementation is able to cache namespaces in memory and an import directive avoids the need to physically copy entries from one namespace data structure into another. The effect is that all header files behave like pre-compiled headers.