Conditional compilation of Objective--c language preprocessing commands (#ifdef, #else, #endif, #if等)

Source: Internet
Author: User
The pre-processing process scans the source code, performs preliminary conversion on it, and generates new source code for the compiler. It can be seen that the pre-processing process processes the source code before the compiler.

In the C language, there is no inherent mechanism to complete the following functions: include other source files during compilation, define macros, and decide whether to include certain code during compilation according to conditions. To complete these tasks, you need to use a preprocessing program. Although most compilers currently include preprocessors, they are generally considered to be independent of the compiler. The pre-processing process reads the source code, checks the statements and macro definitions containing the pre-processing instructions, and converts the source code in response. The preprocessing process also deletes comments and extra blank characters in the program.

The preprocessing instruction is a line of code that starts with a # sign. The # sign must be the first character of the line except for any blank characters. The # followed by the instruction keyword allows any number of blank characters between the keyword and the # sign. The entire line of statements constitutes a preprocessing instruction that will do some conversion of the source code before the compiler compiles. Here are some preprocessing instructions:

Instruction use

#Empty instruction, no effect
#include includes a source code file
#definedefinition macro
#undefCancel a defined macro
#if If the given condition is true, then compile the following code
#ifdefIf the macro has been defined, then compile the following code
#ifndefIf the macro is not defined, compile the following code
#elif If the preceding #if given condition is not true, the current condition is true, then compile the following code
#endifEnd a #if ...... # else conditional compilation block
#errorStop compiling and display error message

First, the file contains
The function of #include preprocessing directive is to expand the included file at the directive. Inclusion can be multiple, that is to say, an included file can also contain other files. The standard C compiler supports at least eight nested inclusions.

The preprocessing process does not check whether a file has been included in the conversion unit and prevents multiple inclusions. In this way, when the same header file is included multiple times, different effects can be achieved by giving conditions at compile time. E.g:

#defineAAA
#include "t.c"
#undefAAA
#include "t.c"

To prevent header files that can only be included once from being included multiple times, you can use compile-time conditions to control the header files. E.g:
/*my.h*/
#ifndefMY_H
#defineMY_H
...
#endif

There are two formats for including header files in the program:
#include <my.h>
#include "my.h"
The first method is to enclose the header file in angle brackets. This format tells the preprocessor to search for included header files in the header files that come with the compiler or external libraries. The second method is to enclose the header file in double quotes. This format tells the preprocessor to search for the included header file in the source code file of the currently compiled application, and if it cannot find it, it searches the header file that comes with the compiler.

The reason for using two different include formats is that the compiler is installed in a public subdirectory, and the compiled applications are in their own private subdirectory. An application contains both public header files provided by the compiler and custom private header files. Using two different include formats allows the compiler to distinguish a common set of header files among many header files.

Second, the macro
Macros define an identifier that represents specific content. The preprocessing process will replace the macro identifiers appearing in the source code with the values defined in the macro. The most common use of macros is to define global symbols that represent a value. The second use of macros is to define macros with parameters. Such macros can be called like functions, but it expands the macro at the calling statement and replaces the formal parameters in the definition with actual parameters at the time of the call.

1. # define directive
#define preprocessing directives are used to define macros. The simplest format of this instruction is: first, an identifier is given, and then the code represented by this identifier is given. In the following source code, these codes are used to replace the identifier. This macro extracts some global values to be 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 reading the program, the symbol MAX_NUM has a specific meaning, the value it represents gives the maximum number of elements that the array can hold. This value can be used multiple times in the program. As a convention, it is customary to always use all capital letters to define macros, so that it is easy to distinguish macro identifiers from program variables and general variable identifiers. If you want to change the size of the array, just change the macro definition and recompile the program.
The value represented by the macro can be a constant expression, which allows including the macro identifier that has been previously defined. E.g:
# defineONE1
# defineTWO2
#defineTHREE (ONE + TWO)
Note that the macro definition above uses parentheses. Although they are not necessary. But for prudent considerations, brackets should still be added. E.g:
six = THREE * TWO;
The preprocessing process converts the above line of code to:
six = (ONE + TWO) * TWO;
If there is no parenthesis, it is converted to six = ONE + TWO * TWO ;.
Macros can also represent a string constant, for example:
#defineVERSION "Version1.0Copyright (c) 2003"

2. #define instruction with parameters
Macros with parameters and function calls look somewhat similar. Look at an example:
#defineCube (x) (x) * (x) * (x)
You can replace any parameter x with any numeric expression or even a function call. Here again remind everyone to pay attention to the use of brackets. The macro is completely enclosed in a pair of parentheses after expansion, and the parameters are also included in parentheses, thus ensuring the integrity of the macro and parameters. See a usage:
intnum = 8 + 2;
volume = Cube (num);
After expansion, it is (8 + 2) * (8 + 2) * (8 + 2);
Without those brackets, it becomes 8 + 2 * 8 + 2 * 8 + 2.
The following usage is unsafe:
volume = Cube (num ++);
If Cube is a function, the above is understandable. However, because Cube is a macro, it will have side effects. Erasing books here is not a simple expression, they will produce unexpected results. They expand like this:
volume = (num ++) * (num ++) * (num ++);
Obviously, the result is 10 * 11 * 12, not 10 * 10 * 10;
So how to use Cube macro safely? The operations that may cause side effects must be moved outside the macro call:
intnum = 8 + 2;
volume = Cube (num);
num ++;

3. # operator
The # operator that appears in the macro definition converts the parameters that follow to a string. Sometimes this usage of # is called stringization operator. E.g:

#definePASTE (n) "adhfkj" #n

main ()
{
printf ("% s", PASTE (15));
}
The # operator in the macro definition tells the preprocessor to convert any parameters passed to the macro in the source code into a string. So the output should be adhfkj15.

4. ## operator
The ## operator is used to connect parameters together. The preprocessor merges the parameters that appear on both sides of ## into a symbol. See the example below:

#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 final program is:
123
aabbcc
Don't worry, unless the need or macro usage happens to be relevant to the job at hand, few programmers will know about the ## operator. Most programmers have never used it.

Three, conditional compilation instructions

Conditional compilation instructions will determine which code is compiled and which is not. The compilation condition can be determined according to the value of the expression or whether a specific macro is defined.

1. # if directive
The #if instruction detects the constant expression following the manufacture of another keyword. If the expression is true, then compile the following code until you know #else, #elif, or #endif appears; otherwise, it will not compile.

2. # endif directive
#endif is used to terminate #if preprocessing instructions.

# defineDEBUG0
main ()
{
#ifDEBUG
printf ("Debugging");
#endif
printf ("Running");
}

Since the program definition DEBUG macro represents 0, the #if condition is false, and the following code is not compiled until #endif, so the program directly outputs Running.
If you remove the #define statement, 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 directive
The #else instruction is used after a #if instruction, and when the condition of the current #if instruction is not true, the code behind #else is compiled. The #endif directive will middle finger above the conditional block.

#defineDEBUG

main ()
{
#ifdefDEBUG
printf ("Debugging");
#else
printf ("Notdebugging");
#endif
printf ("Running");
}

5. # elif directive
The #elif preprocessing directive combines the effects of #else and #if directives.

#defineTWO

main ()
{
#ifdefONE
printf ("1");
#elifdefinedTWO
printf ("2");
#else
printf ("3");
#endif
}
The program is easy to understand, and the final output is 2.

6. Some other standard directives

The #error instruction will cause the compiler to display an error message and then stop compilation.
The #line directive can change the file number and line number used by the compiler to indicate warning and error messages.
The #pragma directive has no formal definition. The compiler can customize its purpose. The typical usage is to prohibit or allow certain annoying warning messages.

supplement:

Preprocessing is the work done before the first pass of lexical scanning and grammatical analysis. To put it bluntly, before the source file is compiled, the pre-processing part is processed first, and then the processed code is compiled. The advantage of this is that the processed code will become very short.
Regarding the file inclusion (#include) and macro definition (#define) in the preprocessing command, the book already has a detailed description, so I wo n’t go into details here. This is mainly to explain the conditional compilation (#ifdef, #else, #endif, #if, etc.). There are three situations as follows:

1: Case 1:
#ifdef _XXXX
... Network 1 ...
#else
... Network 2 ...
#endif
This indicates that if the identifier _XXXX has been defined by the #define command, the program segment 1 is compiled; otherwise, the program segment 2 is compiled.

example: 
#define NUM
.............
.............
.............
#ifdef NUM
printf ("NUM has been defined before! :)");
#else
printf ("NUM has not been defined before! :(");
#endif
}
If there is a line #define NUM at the beginning of the program, that is, NUM is defined, when the #ifdef NUM below is encountered, of course the first printf is executed. Otherwise the second printf will be executed.
I think that with this method, you can easily turn on / off a specific function of the entire program.

2: Case 2:
#ifndef _XXXX
... Network 1 ...
#else
... Network 2 ...
#endif
#Ifndef is used here, which means if not def. Of course, it is the opposite of #ifdef (if the identifier _XXXX is not defined, then execute block 1, otherwise execute block 2). Examples are not given.

3: Case 3:
#if constant
... Network 1 ...
#else
... Network 2 ...
#endif
This means that if the constant is true (not 0, any number, as long as it is not 0), block 1 is executed, otherwise block 2 is executed.
I think that this method can add test code. When you need to start the test, just change the constant to 1. When not testing, just change the constant to 0.

Objective--Conditional compilation of C language preprocessing commands (# ifdef, # else, # endif, # if, etc.)
Related Article

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.