Miscellaneous Preprocessor Directives in C
With this lesson we conclude the study of the C language preprocessor.
We will see here the last three directives that the preprocessor makes available: #error, #line and #pragma.
These are directives that are rarely used, but that can be very useful in certain situations.
Directive #error
The preprocessing directive #error has the following syntax:
#error message
Where message is a sequence of characters that represents the error message to display.
When the preprocessor encounters the #error directive, it interrupts the compilation and displays the specified error message.
This directive is used to indicate serious problems of the program during compilation. In fact, it is always used in conjunction with conditional compilation.
Let's see an example. Suppose we write a program that must not be compiled for a machine or system that does not support the floating point type. In this case, we can use the #error directive to interrupt the compilation and display an error message.
#if !defined(__STDC_IEC_559__)
#error "The system does not support the floating point type"
#endif
In this example, if the system does not support the floating point type, the compilation will be interrupted and the message "The system does not support the floating point type" will be displayed.
Similarly, suppose that our program requires that int integers are stored using at least 32 bits or 4 bytes. We can write the following code:
#include <limits.h>
#if INT_MAX < 2147483647
#error "The int type is too small"
#endif
In the limits.h file the constants INT_MAX and INT_MIN are defined, which represent the maximum and minimum value that an int can store. If an int integer is represented with 32 bits, then the maximum it can store is:
Therefore, if INT_MAX is less than 2147483647, then the int type does not use 32 bits and the compilation will be interrupted with the message "The int type is too small".
Often, the #error directive is found in the #else clause of an #if or #ifdef directive. For example:
#if defined(__linux__)
/* Code for Linux */
#else
#error "This program requires a Linux operating system"
#endif
Directive #error
The preprocessing directive #error interrupts the compilation and displays a specified error message.
The syntax is:
#error message
Where message is the error message to display.
Directive #line
The preprocessing directive #line has the following syntax:
#line number "file"
This directive is rarely used. Its purpose, in fact, is to modify the value of the __LINE__ and __FILE__ macros. Therefore, for example, if we write:
#line 42 "file.c"
From this point forward, __FILE__ will return "file.c" and __LINE__ will return a progressive value starting from 42.
The second consequence of this directive is that any error message shown by the compiler will indicate as file file.c and as line number the number obtained from the number of lines that follow the #line directive plus 42.
Why use such a directive? In general, it is never used by developers, but it is useful for development and debug tools.
There are several tools that generate C code. For example, programming language parsers, markup language compilers, code generation tools, etc. These tools can use the #line directive to indicate to the compiler the position of the generated code within the original source file.
We can imagine, for example, a tool that takes as input a file written in a language called languageX and generates a C file. Suppose this tool takes as input a file with extension .x and generates a file with extension .c. In this case, the tool could use the #line directive to indicate to the compiler the position of the generated code within the .x file:
#line 10 "file.x"
In this way, if the compiler finds an error in file.c, the tool can map the error to the corresponding line in file.x.
Directive #line
The preprocessing directive #line modifies the value of the __LINE__ and __FILE__ macros.
The syntax is:
#line number "file"
Where number is the line number and file is the name of the file.
Directive #pragma
The last preprocessing directive we will see is #pragma. This directive is used to provide information to the compiler or to control the behavior of the compiler.
The syntax is:
#pragma command
Through it, we can pass specific commands to the compiler. However, such commands are not standardized and can vary from compiler to compiler. Therefore, to know which ones are available it is always advisable to consult the documentation of the compiler being used.
The C99 standard introduces standardized commands for the #pragma directive. We will see them in detail later.
Directive #pragma
The preprocessing directive #pragma is used to send specific commands to the compiler.
The syntax is:
#pragma command
The specific commands can vary from compiler to compiler.
In Summary
With this lesson we have concluded our study of the C preprocessor.
We have studied the three remaining directives: #error, #line and #pragma.
-
The
#errordirective interrupts the compilation and displays an error message.It is used to indicate serious problems of the program during compilation and is always used in conjunction with conditional compilation.
-
The
#linedirective modifies the value of the__LINE__and__FILE__macros. Furthermore, it modifies the way the compiler counts lines and files.It is rarely used by developers, but it is useful for development and debug tools.
-
The
#pragmadirective is used to send specific commands to the compiler.The specific commands can vary from compiler to compiler.