Conditional compilation of C language pre-processing commands (# ifdef, # else, # endif, # If, etc)

Source: Internet
Author: User
Tags define definition

 

The pre-processing process scans the source code and performs initial conversion to generate new source code for the compiler. It can be seen that the preprocessing process processes the source code prior to the compiler.

In C language, there is no internal mechanism to complete the following functions: including other source files, definition macros during compilation, and determining whether to include certain code during compilation based on conditions. To do this, you need to use a Preprocessing Program. Although most compilers currently contain preprocessing programs, they are generally considered independent of compilers. The Preprocessing process reads the source code, checks the statements and macro definitions that contain the preprocessing commands, and converts the source code. The pre-processing process also deletes comments and extra spaces in the program.

The pre-processing command starts. # It must be the first character of the row except for any blank characters. # Followed by the command keyword. Any number of blank characters can exist between the keyword and. A full-line statement constitutes a preprocessing command that converts the source code before the compiler compilation. The following are some pre-processing commands:

Command usage

# Empty command, no effect
# Include contains a source code file
# Define definition macro
# UNDEF cancel a defined macro
# If the given condition is true, compile the following code
# Ifdef if the macro has been defined, compile the following code
# Ifndef if the macro is not defined, compile the following code
# Elif if the previous # if given condition is not true and the current condition is true, compile the following code:
# Endif end one. # If ...... # Else Conditional compilation Block
# Error stops compilation and displays error information

1. File Inclusion
# The include pre-processing command is used to expand the contained files in the command. Multiple files can be included, that is, a contained file can also contain other files. The standard C compiler supports at least eight-fold nested inclusion.

The Preprocessing process does not check whether a file is included in the conversion unit and prevents multiple inclusion of the file. In this way, different results can be achieved by specifying the compiling conditions when the same head file is included multiple times. For example:

# Defineaaa
# Include "T. C"
# Undefaaa
# Include "T. C"

To prevent header files that can only be contained once from being contained multiple times, you can use compile-time conditions to control the header files. For example:
/* My. H */
# Ifndefmy_h
# Definemy_h
......
# Endif

The program contains header files in two formats:
# Include <my. h>
# Include "My. H"
The first method is to enclose the header file with Angle brackets. This format tells the Preprocessing Program to search for included header files in the header files of the compiler or external library. The second method is to enclose the header file with double quotation marks. This format tells the Preprocessing Program to search for the contained header file in the source code file of the currently compiled application. If it cannot be found, it will then search for the header file that comes with the compiler.

The reason for using two different inclusion formats is that the compiler is installed in public subdirectories, And the compiled applications are in their own private subdirectories. An application contains both common header files provided by the compiler and custom private header files. Two different inclusion formats enable the compiler to differentiate a set of common header files from many header files.

Ii. macros
A macro defines an identifier that represents a specific content. The Preprocessing process replaces the macro identifier in the source code with the value of the macro definition. The most common usage of macros is to define the global symbols that represent a value. The second usage of macros is to define macros with parameters. Such macros can be called like functions, but they expand macros in the call statement, replace the formal parameters in the definition with the actual parameters used for the call.

1. # define command
# Define preprocessing commands are used to define macros. The simplest format of this command is: first, an identifier is a God, and then the Code represented by this identifier is given. In the following source code, use the code to replace the identifier. This macro extracts some global values used in the program and assigns them to some memory identifiers.
# Definemax_num10
Intarray [max_num];
For (I = 0; I <max_num; I ++ )/*...... */

In this example, for the person who reads the program, the symbol max_num has a specific meaning. The value represents the maximum number of elements that an array can hold. This value can be used multiple times in the program. As a convention, the macro is always defined by uppercase letters, which makes it easy to distinguish the macro identifier of the program red from the general variable identifier. To change the array size, you only need to change the macro definition and re-compile the program.
The macro value can be a constant expression, which can include the previously defined macro identifier. For example:
# Defineone1
# Definetwo2
# Definethree (one + two)
Note that the macro definition above uses parentheses. Although they are not necessary. But for careful consideration, brackets should be added. For example:
Six = three * Two;
The Preprocessing process converts the previous line of code:
Six = (one + two) * Two;
Without the parentheses, convert them to six = one + two * Two.
A macro can also represent a String constant, for example:
# Defineversion "version1.0copyright (c) 2003"

2. # define command with Parameters
Macros with parameters seem similar to function calls. Let's look at an example:
# Definecube (x) * (X)
Any numeric expression or function call can be used to replace parameter X. Here, we will remind you to pay attention to the use of parentheses. The macro extension is completely included in a pair of parentheses and the parameters are included in the brackets, which ensures the integrity of the macro and parameters. Let's look at the usage:
Intnum = 8 + 2;
Volume = cube (Num );
Expanded to (8 + 2) * (8 + 2) * (8 + 2 );
If no parentheses exist, they are changed to 8 + 2*8 + 2*8 + 2.
The following usage is insecure:
Volume = cube (Num ++ );
The preceding method is understandable if cube is a function. However, cube is a macro, which produces side effects. Here, the book cleanup is not a simple expression, and they will produce unexpected results. They expand like this:
Volume = (Num ++) * (Num ++ );
Obviously, the result is 10*11*12 instead of 10*10*10;
So how can we safely use cube Macros? Operations that may cause side effects must be moved out of macro calls:
Intnum = 8 + 2;
Volume = cube (Num );
Num ++;

3. # Operators
The # operator that appears in the macro definition converts the parameter following it into a string. Sometimes the # In this usage is called a string operator. For example:

# Definepaste (n) "adhfkj" # N

Main ()
{
Printf ("% s", paste (15 ));
}
The # operator in the macro definition tells the Preprocessing Program to convert any parameter passed to the macro in the source code into a string. So the output should be adhfkj15.

4. ## Operators
# Operators are used to connect parameters together. The Preprocessing Program combines the parameters on both sides of # Into a symbol. See the following example:

# Definenum (a, B, c) A # B # C
# Definestr (a, B, c) A # B # C

Main ()
{
Printf ("% d", num (1, 2, 3 ));
Printf ("% s", STR ("AA", "BB", "cc "));
}

The output of the program is:
123
Aabbcc
Do not worry. Unless necessary or macro usage is related to the work at hand, few programmers will know the # operator. Most programmers have never used it.

Iii. Conditional compilation commands

The Conditional compilation command determines which codes are compiled and which ones are not compiled. You can determine the compilation conditions based on the expression value or whether a specific macro is defined.

1. # If command
# The if command detects the constant expression following the creation of another keyword. If the expression is true, the code after compilation will be known until # else, # Elif or # endif appears; otherwise, the compilation will not be performed.

2. # endif command
# Endif is used to terminate # If preprocessing command.

# Definedebug0
Main ()
{
# Ifdebug
Printf ("debugging ");
# Endif
Printf ("running ");
}

Because the debug macro defined by the program represents 0, the # If condition is false, and the subsequent code is not compiled until # endif, so the program directly outputs the running.
If the # define statement is removed, the effect is the same.

3. # ifdef and # ifndef
# Definedebug

Main ()
{
# Ifdefdebug
Printf ("yes ");
# Endif
# Ifndefdebug
Printf ("no ");
# Endif
}
# Ifdefined is equivalent to # ifdef; # If! Defined is equivalent to # ifndef

4. # else command
# When the else command is used after a # If Command and the current # If command condition is not true, the code after # else is compiled. # The endif command specifies the above condition block.

# Definedebug

Main ()
{
# Ifdefdebug
Printf ("debugging ");
# Else
Printf ("notdebugging ");
# Endif
Printf ("running ");
}

5. # Elif command
# Elif preprocessing commands combine the functions of # else and # If commands.

# Definetwo

Main ()
{
# Ifdefone
Printf ("1 ");
# Elifdefinedtwo
Printf ("2 ");
# Else
Printf ("3 ");
# Endif
}
The program is well understood, and the final output result is 2.

6. Other Standard Commands

# The error command displays an error message for the compiler and stops compilation.
# The line command can change the file number and line number used by the compiler to indicate warnings and error messages.
# The Pragma command is not formally defined. The compiler can customize its usage. A typical usage is to disable or allow some annoying warning information.

Supplement:

Preprocessing is the work done before the first lexical scan and syntax analysis of compilation. To put it bluntly, it is to process the preprocessing part before compiling the source file, and then compile the processed code. The advantage of doing so is that the processed code will become very short.
For the file inclusion (# include) and macro definition (# define) in the pre-processing command, detailed descriptions are provided in the book and will not be detailed here. Here we mainly describe Conditional compilation (# ifdef, # else, # endif, # If, etc. There are three situations:

1: Case 1:
# Ifdef _ xxxx
... Program section 1...
# Else
... Program section 2...
# Endif
This indicates that if the identifier _ XXXX has been defined by the # define command, the program segment 1 will be compiled; otherwise, the program segment 2 will be compiled.

Example:
# Define num
.............
.............
.............
# Ifdef num
Printf ("previously defined num! :)");
# Else
Printf ("no definition of num before! :(");
# Endif
}
If the program starts with the # define num line, that is, the num is defined. When we encounter the # ifdef num below, of course the first printf is executed. Otherwise, the second printf will be executed.
In my opinion, you can easily enable/disable a specific function of the entire program.

2: Case 2:
# Ifndef _ xxxx
... Program section 1...
# Else
... Program section 2...
# Endif
# Ifndef is used here, indicating if not def. Of course, it is the opposite of # ifdef (if the identifier _ XXXX is not defined, the execution segment 1; otherwise, the execution Segment 2 ). This is not an example.

3: Case 3:
# If constant
... Program section 1...
# Else
... Program section 2...
# Endif
It indicates that if the constant is true (not 0, whatever number, as long as it is not 0), the program segment 1 will be executed; otherwise, the program segment 2 will be executed.
I think this method can be used to add the test code. To enable the test, you only need to change the constant to 1. Instead of testing, you only need to change the constant to 0.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.