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

#include <filename>

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

#include "filename"

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

#define IDENTIFIER substitution_list

substitution_list can contain:

  • Identifiers

  • Keywords

  • Numeric constants

  • Character constants

  • String literals

  • Operators

  • Punctuation characters

Examples:

  • Numeric constant

    #define FREEZING_PT 32.0f
  • Boolean values

    #define TRUE 1
    #define FALSE 0

Parametric Macro

#define IDENTIFIER(x1,x2,…,xn) substitution_list

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

    #define MAX( x, y ) ( ( x > y ) ? ( x ) : ( y ) )
  • Square computation

    #define SQUARE(x) (x)*(x)

Definition of macro outside the program

gcc  -DMACRO_NAME=value filename.c

Useful operators within a macro

defined

defined(IDENTIFIER)

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

# variable_name

It returns a string whose content is "variable_name"

Token-pasting

token ## token

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

Example:

#define MK_ID(n) i##n
int MK_ID(1);

After the preprocessing:

int  i1;

Flow control

#ifdef

#ifdef IDENTIFIER
directives/instructions
#endif

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

#ifndef

#ifndef IDENTIFIER
directives/instructions
#endif

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

#if, #elif and #else

#if  expr1			
directives1/instructions1
#elif  expr2			
directives2/instructions2

#else
directivesN/instructionsN
#endif

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

Other directives

#error

#error token-string

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

#line

#line  n

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, ...

#line n "filename"

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.

#pragma token
  • 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:

#pragma data(heap_size => 1000, stack_size => 2000)

Destringation

_Pragma( "literal_string" )			
  • 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