Pre-processor

Preprocessor directives

Subset of the compiler that has its own syntax analyzer for program lines in order to perform the following operations:

  • Inclusion of other files into the source file (#include)

  • Definition directives (#define)

  • Conditional compilation of source code (#if, #ifdef, #ifndef, ...)

\: go to the next line in the definition of a directive (if it is organized over multiple lines)

#include

It includes the specified file in the directive in place of the directive itself

The preprocessor looks for the file to include in the default include path for C files.

The preprocessor looks for the file to include in the source file's directory first, then in the standard directory.

#define (Macro substitution)

The preprocessor expands the macro by replacing it with its value (syntactic substitution of the code block).

Macro Types

Simple Macro

substitution_list can contain:

  • Identifiers

  • Keywords

  • Numeric constants

  • Character constants

  • String literals

  • Operators

  • Punctuation characters

Examples:

  • Numeric constant

  • Boolean values

Parametric Macro

The first parenthesis must be attached to the IDENTIFIER and separated from the first parameter by a space.

It allows identifying where the parameters start.

Examples:

  • Max beetwen two numbers

  • Square computation

Definition of macro outside the program

Useful operators within a macro

defined

It returns 1 if IDENTIFIER was not defined

  • All parameters inserted must appear in the substitution_list

  • Inside a macro, there can be calls to other macros

  • Macro definitions remain valid until the end of the file in which they appear

  • A MACRO cannot be defined twice in the same file

Stringization

It returns a string whose content is "variable_name"

Token-pasting

It returns a string formed by the concatenation of the two tokens.

Example:

After the preprocessing:

Flow control

#ifdef

directives/instructions are seen by the preprocessor only if IDENTIFIER has already been defined.

#ifndef

directives/instructions are seen by the preprocessor only if IDENTIFIER has not been defined.

#if, #elif and #else

where expr1, ..., exprN are relational or logical expressions.

Other directives

#error

It generates an error message token-string defined during compilation and terminates the compilation.

#line

It alters the way in which the lines of a program are numbered. The lines after the directive are numbered as n+1, n+2, ...

The compiler assumes that the following lines of the program:

  • are numbered starting from n (as n+1, n+2, ...)

  • come from the file filename

#pragma

A way to request a special behavior from the compiler.

  • It can be a simple directive (single token)

  • The preprocessor does not ignore the instruction only if it contains a recognized command (otherwise, no error would be generated)

  • It can be a very complex directive

Example:

Destringation

  • The double quotes at the ends of "string_literal" are removed

  • The escape sequences \" and \\ are replaced with " and \ respectively

Predefined macros

Macro
Description

__FILE__

File name being compiled

__DATE__

Compilation date (Mmm dd yyyy)

__TIME__

Compilation time (hh:mm:ss)

__STDC__

1 if the compiler conforms to the C Standard (C89 / C99)

__LINE__

Current line number being compiled

System predefined macros

Macro
Description

_WIN32

Defined for Win32 and Win64 applications (Always defined)

_WIN64

Defined for Win64 applications

__linux__

Defined for Linux applications

__unix__

Defined for Unix applications (not included in linux)

__POSIX__

Defined for POSIX applications

__APPLE__

Defined for Apple applications

Predefined macros added with C99

Macro
Description

__STDC__HOSTED__

1 if this is a hosted implementation 0 if it is a freestanding implementation

__STDC__VERSION

Supported version of the C Standard

__STDC_IEC_559_

1 if IEC 60559 floating-point arithmetic is supported

__STDC__IEC_559_COMPLEX__

1 if IEC 60559 complex arithmetic is supported

__STDC_ISO_10646__

yyyymmL if wchar_t values comply with the ISO 10646 standard of the specific year and month

__func__

returns the name of the currently executing function

Last updated