C/C ++ macro summary C program source code may include various compilation instructions

Source: Internet
Author: User

The macro in the forum. C/C ++ summarizes various compilation commands in the source code of the C program. These commands are called preprocessing commands. Although they are not actually part of the C language, they extend the C programming environment. This section describes how to use preprocessing programs and annotations to simplify the program development process and improve the readability of the program. The C language Preprocessing Program defined by ANSI standard includes the following commands: # define, # error, # I nclude, # if, # else, # elif, # endif, # ifdef, # ifndef, # undef, # line, # pragma, etc. Obviously, all the pre-processing commands start with a symbol #, which is described below. 1. # define command # define defines an identifier and a string. Each time This identifier is encountered in the source program, it is replaced by a defined string. The ANSI standard defines the identifier as a macro name, and the replacement process is called macro replacement. The command is generally in the form of: # define identifier string Note :? This statement does not have a semicolon. There can be any space between the identifier and the string. Once the string starts, it ends only with a new row.? After the macro name is defined, it can become part of other macro name definitions.? Macro replacement only replaces macro identifiers with text strings, provided that the macro identifiers must be identified independently. Otherwise, the macro identifiers are not replaced. For example: # define XYZ this is a test, use the macro printf ("XYZ"); // print "XYZ" without printing "this is a test ". Because the pre-compiler does not recognize "XYZ "? If the string is longer than one row, you can use a backslash '\' to continue the row at the end of the row. 2. # error processor command # error forces the Compilation Program to stop compilation, which is mainly used for program debugging. 3. # I nclude command # I nclude enables the compiler to embed another source file into the source file with # I nclude. The source file to be read must be enclosed by double quotation marks or angle brackets. For example, the # I nclude "stdio. h" or # I nclude lines use the C compiler to read and compile the subroutine used to process the disk file library. Embedding a file into a file in the # I nclude command is feasible. This method is called nested embedded files. The nested layers depend on the specific implementation. If the explicit path name is part of the object identifier, search for the embedded object in only the subdirectories. Otherwise, if the file name is enclosed in double quotation marks, the current working directory is retrieved first. If no file is found, search all directories described in the command line. If no file is found, search for the standard directory defined during implementation. If there is no explicit path name and the file name is enclosed by Angle brackets, it is first retrieved in the directory of the compiled command line. If the file is not found, the standard directory is retrieved and the current working directory is not retrieved. 4. The Conditional compilation command provides several commands to selectively compile each part of the program's source code. This process is called Conditional compilation. Commercial software companies widely use Conditional compilation to provide and maintain many customer versions of a program. # If, # else, # elif and # endif # the general meaning of if is that if the constant expression after # if is true, the code between it and # endif is compiled, otherwise, skip the code. Command # endif identifies the end of a # if block. # If constant-expression statement sequence # endif the expression following # if is evaluated during compilation. Therefore, it must contain only constants and defined identifiers and cannot use variables. The expression does not contain the operator sizeof (sizeof is also a value during compilation ). # The else command functions a bit like the else in C; # else creates another option (in the case of # if failure ). Note: # else belongs to the # if block. # The elif command has the same meaning as the else if command. It forms an if else-if step-by-step statement and supports multiple compilation options. # Elif followed by a constant expression. If the expression is true, the code block after compilation is not tested for other # elif expressions. Otherwise, test the next part in sequence. # If expression statement sequence # elif expression1 statement sequence # endif in nested Conditional compilation # endif, # else or # elif matches with recent # if or # elif. # Another method for ifdef and # ifndef Conditional compilation is to use the # ifdef and # ifndef commands, which respectively indicate "if there is a definition" and "if there is no definition ". # The general form of ifdef is: # ifdef macroname statement sequence # endif # ifdef and # ifndef can be used in # if, # else, # elif statement, but must be with a # endif. 5. # undef command # undef the macro name defined previously after undef is canceled. The general format is: # undef macroname 6, # line command # line changes the content of _ LINE _ and _ FILE _. They are pre-defined identifiers in the Compilation Program. The basic format of the command is as follows: # line number ["filename"] Where the number is any positive integer, and the optional file name is any valid file identifier. The row number is the current row number in the source program, and the file name is the name of the source file. Command # line is mainly used for debugging and other special applications. Note: The numeric marker after # line starts from the next row. 7. the predefined macro name ANSI standard describes the five predefined macro names in C. They are: _ LINE _ FILE _ DATE _ TIME _ STDC _ If the compilation is not standard, only a few of the above macro names are supported, or they are not supported at all. Remember that the Compilation Program may also provide other predefined macro names. The _ LINE _ and _ FILE _ macro commands have been discussed in the # line Section. The remaining macro names are discussed here. The _ DATE _ macro command contains a string in the form of month, day, or year, which indicates the DATE when the source file was translated to the code. The TIME when the source code is translated to the target code is included in _ TIME _ as a string. String format: minute: second. If the implementation is standard, macro _ STDC _ contains the decimal constant 1. If it contains any other number, the implementation is non-standard. When compiling a C ++ program, the compiler automatically defines a pre-processing name__ cplusplus. When compiling a standard C program, the compiler automatically defines the name _ STDC __. Note: The macro name is written by an identifier and two underscores (_) on both sides. (Part of the content from: http://www.bc-cn.net/Article/kfyy/cyy/jc/200511/919.html) 8, C, C ++ macro appear in the #, # @, # In the macro, # The function is to Stringfication the macro parameters following it. Simply put, a double quotation mark is added to the left and right sides after the macro variables referenced by it are replaced. # Is called a concatenator to connect two tokens into one. Note that the connected object is a Token, not necessarily a macro variable. For example, you want to create an array composed of a menu item command name and a function pointer, and you want to have an intuitive and name relationship between the function name and the menu item command name. You can use the macro parameter # fixed part. Of course, you can also use n # symbols to connect n + 1 Token. This feature is also not available for # symbols. # @: The function is to character the macro parameters following it. 9. variable parameters in Macro C... in Macro C are called Variadic Macro, that is, variable Macro. For example: # define myprintf (templt ,...) fprintf (stderr, templt ,__ VA_ARGS _) or # define myprintf (templt, args ...) in the first macro of fprintf (stderr, templt, args), the default macro _ VA_ARGS _ is used instead of the variable parameter. In the second macro, we explicitly name the variable parameter as args, so we can use args to represent the variable parameter in the macro definition. Like stdcall in C, the variable parameter must appear at the end of the parameter table. When the macro above can only provide the first parameter templt, the C standard requires us to write it in the form of myprintf (templt. The replacement process is myprintf ("Error! \ N ",); replace with: fprintf (stderr," Error! \ N ",). This is a syntax error and cannot be compiled properly. There are two solutions to this problem. First, the solution provided by gnu cpp allows the preceding macro call to be written as: myprintf (templt), and it will be replaced with: fprintf (stderr, "Error! \ N ",); obviously, compilation errors will still be generated here (not in some cases in this example ). In addition to this method, both c99 and gnu cpp support the following macro definition method: # define myprintf (templt ,...) fprintf (stderr, templt, ##__ VAR_ARGS _) at this moment, # the function of this connection symbol is when _ VAR_ARGS _ is empty, remove the preceding comma. The translation process is as follows: myprintf (templt); is converted to: fprintf (stderr, templt); in this way, if the templt is valid, no compilation error will be generated. 10. # Use of pragma [reprinted] among all preprocessing commands, # The Pragma command may be the most complex, it is used to set the status of the compiler or to instruct the compiler to complete some specific actions. # The pragma command provides a method for each compiler to provide the unique features of the host or operating system while maintaining full compatibility with C and C ++ languages. According to the definition, the compilation instructions are proprietary to machines or operating systems and are different for each compiler. The format is generally: # Pragma Para, where Para is a parameter. The following describes some common parameters. (1) message parameter. The Message parameter is one of my favorite parameters. It can output relevant information in the compilation information output window, which is very important for controlling source code information. The usage is as follows: # Pragma message ("message text") when the compiler encounters this instruction, it prints the message text in the compilation output window. When we define many Macros in the program to control the source code version, we may forget whether these macros are correctly set, in this case, we can use this command to check it during compilation. Suppose we want to determine if we have defined the _ X86 macro in the source code. We can use the following method # ifdef _ X86 # Pragma message ("_ X86 macro activated! ") # Endif when we define the _ X86 macro, the application will display" _ X86 macro activated in the compilation output window during compilation! ". We won't be scratching our heads because we don't remember some specific macros we defined. (2) The other pragma parameter that is used more frequently is code_seg. The format is as follows: # pragma code_seg (["section-name" [, "section-class"]). It can set the code segment for storing function code in the program, we use the driver when developing it. (3) # pragma once (commonly used) as long as this command is added at the beginning of the header file, the header file can be compiled once. This command is actually available in VC6, however, considering the compatibility, It is not used much. (4) # pragma hdrstop indicates that the pre-compiled header file ends here, and the subsequent header files are not pre-compiled. BCB can pre-compile the header file to speed up the link, but if all header files are pre-compiled, it may occupy too much disk space. Therefore, this option is used to exclude some header files. Sometimes there is A dependency between units. For example, unit A depends on unit B. Therefore, Unit B must be compiled before unit. You can use # pragma startup to specify the compilation priority. If # pragma package (smart_init) is used, BCB will be compiled based on the priority. (5) # pragma resource "*. dfm" indicates adding resources in the *. dfm file to the project. *. Dfm defines the form and appearance. (6) # pragma warning (disable: 4507 34; once: 4385; error: 164) is equivalent to: # pragma warning (disable: 4507 34) // no warning messages 4507 and 34 are displayed # pragma warning (once: 4385) // only one warning message is reported # pragma warning (error: 4385) // use the 164 warning as an error. At the same time, This pragma warning also supports the following format: # pragma warning (push [, n]) # pragma warning (pop) Where n represents a warning level (1---4 ). # Pragma warning (push) saves the existing warning status of all warning information. # Pragma warning (push, n) saves the existing warning status of all warning information and sets the global warning level to n. # Pragma warning (pop) pops up the last warning message to the stack, and all changes made between the inbound and outbound stacks are canceled. Example: # pragma warning (push) # pragma warning (disable: 4705) # pragma warning (disable: 4706) # pragma warning (disable: 4707) //....... # pragma warning (pop) resaves all warning information (including 4707, and) at the end of this Code ). (7) pragma comment (...) This command puts a comment record into an object file or executable file. Common lib keywords can help us to connect to a library file. (8) the traditional method to export dll functions from pragma is to use the module definition file (. def), Visual C ++ provides a more concise and convenient method, that is, "_ declspec ()" followed by "dllexport", telling the connection to export this function, for example: _ declspec (dllexport) int _ stdcall MyExportFunction (int iTest); Put "_ declspec (dllexport)" at the beginning of the function declaration, after the generated DLL is connected, the function "_ MyExportFunction @ 4" is exported ". The name of the export function above may not be what I want. We want to export the original "MyExportFunction ". Fortunately, VC provides a pre-processing indicator "# pragma" to specify the connection options (not only this function, but also many indication functions), as follows: # pragma comment (linker, "/EXPORT: MyExportFunction = _ MyExportFunction @ 4") This is just a wish for the day :). If you want to specify the export sequence, or export the function as the serial number without Entryname, this preprocessing indicator (specifically the connector) can be implemented. Let's take a look at the MSDN syntax description: /EXPORT: entryname [, @ ordinal [, NONAME] [, DATA] @ ordinal specifies the sequence. NONAME indicates that only the function is exported as the sequence number. The DATA keyword specifies that the EXPORT item is a DATA item. Every compilation program can use the # pragma command to activate or terminate some compilation functions supported by the Compilation Program. For example, for loop optimization: # pragma loop_opt (on) // activation # pragma loop_opt (off) // termination sometimes, some functions in the program will give the compiler A warning that you are familiar with and want to ignore, such as "Parameter xxx is never used in function xxx". You can do this: # pragma warn-100 // Turn off the warning message for warning #100 int insert_record (REC * r) {/* function body */} # pragma warn + 100 // Turn the warning message for warning #100 back on function will generate a warning message with a unique signature 100, this warning can be temporarily terminated. Each compiler has different implementations for # pragma, and the effectiveness in one compiler is almost ineffective in other compilers. You can view it in the compiler documentation. Usage # Use of pragm pack () # alignment length specified by pragma pack. The actual usage rules are as follows :? Structure, union, or data member of the class. The first one is placed in a place with the offset of 0, and the alignment of each data member is later, follow the value specified by # pragma pack and the smaller value of the member length.? That is to say, when the value of # pragma pack is equal to or greater than the length of all data members, the size of this value will not produce any effect.? The overall alignment of the structure is performed based on the smaller value between the largest data member in the structure and the value specified by # pragma pack. Note: The use of # pragma pack (n) in the file changes the default setting and does not recover. Generally, you can use # pragma pack (push, n) and # pragma pack (pop) set and restore. Note: The content of macro functions is discussed in another topic. The misunderstanding of macro usage has been mentioned in the text when macro is described. Finally, an example is provided, the Side Effect in the description refers to the impact of multiple Evaluation (that is, the value) on the program when the macro expands its parameters. Assume that a 32 B register (REG) is saved in a system. A high 16 B represents a meaning, low 16 B represents another meaning (which often appears in programs ). Now we need to separate high and low 16 bits without considering the special requirements in practice. Write the code as: # define High16bit (REG) (REG> 16) # define Low16bit (REG) (REG <16)> 16) This function is sufficient in most cases and is not discussed here. This article focuses on the negative impact of this writing method. If High16bit and Low16bit are not used in different statements in the program, it may be Side effect, and the specific register REG is the Status Register, the status may change at any time, so the problem is that the Status Register of high/low 16 B is not at the same time. It is difficult to find such errors in the program. Here I have relaxed the conditions. In a macro, it is even more difficult to consider the problem of multiple values of a parameter.

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.