# Pragma is the most complex preprocessing command in C ++. The following are the most common commands # pragma commands:
# Pragma comment (Lib, "XXX. lib ")
Link to the library XXX. Lib, which is the same effect as writing XXX. Lib in the Project Settings.
# Pragma comment (linker, "/entry: main_function ")
Specifies the linker option/entry: main_function
# Pragma once
Indicates that the file is contained only once.
# Pragma warning (Disable: 4705)
Indicates that warning 4705 is blocked.
Each execution of C and C ++ programs supports some unique features of the host or operating system. For example, some programs need to precisely control the memory area where data is stored or control a function.
Number of received parameters. # Pragma provides the compiler with a method to compile on different machines and operating systems to maintain full compatibility between C and C ++. # Pragma is defined by machines and related operating systems
Is usually different for each compiler.
If the compiler encounters an unknown Pragma command, it will give a warning and continue the compilation. The Microsoft C and C ++ compiler recognizes the following commands: alloc_text,
Auto_inline, bss_seg, check_stack, code_seg, comment, component, conform, const_seg, data_seg, deprecated,
Fenv_access, float_control, fp_contract, function, hdrstop, include_alias, init_seg, inline_depth, inline_recursion, intrinsic,
Make_public, managed, message, OMP, once, optimize, pack, pointers_to_members, pop_macro, push_macro, region,
Endregion, runtime_checks, section, setlocale, strict_gs_check, unmanaged, vtordisp, and warning. Conform, init_seg,
Pointers_to_members and vtordisp are only supported by the C ++ compiler.
The following is a detailed explanation of common Pragma commands.
1. # pragma once. Ensure that the file is only contained once. It is based on disk files, while # ifndef is based on macros.
2. # pragma warning. Allows you to selectively modify the warning messages of the compiler. It has the following usage:
# Pragma warning (Disable: 4507 34; once: 4385; error: 164) is equivalent:
# Pragma warning (Disable: 4507 34) // do not display the 4507 and 34 Warnings
# Pragma warning (once: 4385) // only one warning message is reported once
# Pragma warning (error: 164) // use the 164 warning message as an error
# Pragma warning (default: 176) // reset the 176 warning behavior of the compiler to the default status
This pragma warning also supports the following format, where n represents a warning level (1---4 ):
# Pragma warning (push) // Save the existing warning status of all warning information
# Pragma warning (push, n) // Save the existing warning status of all warning information and set the Global Alarm level to n
# Pragma warning (POP )//
For example:
# Pragma warning (push)
# Pragma warning (Disable: 4705)
# Pragma warning (Disable: 4706)
# Pragma warning (Disable: 4707)
# Pragma warning (POP)
After this code, all warning messages (including 4707, and) are restored ).
3. # pragma hdrstop. Indicates that the header file is pre-compiled till now, and the header file is not pre-compiled. BCB can pre-compile the header file to speed up the link, but if all the header files are
Row pre-compilation may occupy too much disk space, so use this option to exclude some header files.
4. # pragma message. Output the specified text information on the standard output device without stopping the program. 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.
5. # pragma data_seg. It is generally used in DLL. It can set the data segment of the initialization variable in the program in the OBJ file. If no parameter is specified, the initialization variable is placed in the default number.
Data Segment. Data has the following usage:
1: # pragma data_seg ("shared") // defines the data segment "shared", where there are two variables A and B
2: int A = 0; // stored in the data segment "shared"
3: int B; // It is stored in the data segment ". BSS" because it is not initialized.
4: # pragma data_seg () // indicates that the data segment "shared" is over. The code for this row is optional.
Special initialization of variables is very important, otherwise the compiler will put them in common uninitialized data segments rather than in shared. For example, the above variable B is actually placed in the uninitialized number.
Data Segment. BSS.
1: #pragma data_seg("Shared")
2: Int J = 0; // stored in the data segment "shared"
3: # pragma data_seg (push, stack1, "shared2") // define the data segment shared2, assign the record to the alias stack1, and then put it into the internal compiler stack.
4: int L = 0; // stored in the data segment "shared2"
5: # pragma data_seg (POP, stack1) // records are popped up from the internal compiler stack until stack1 is popped up. If stack1 is not displayed, no operation is performed.
6: int m = 0; // The variable is stored in the data segment "shared". If no pop segment exists, the variable is stored in the data segment "shared2 ".
6. # pragma code_seg. It can set the code segment of the function in the program in the OBJ file. If no parameter is specified, the function is placed in the default code segment. text, which has the following usage:
1: void func1 () {// It is stored in the code segment. Text by default.
2: }
3:
4: #pragma code_seg(".my_data1")
5:
6: void func2 () {// stored in code snippet. my_data1
7: }
8:
9: #pragma code_seg(push, r1, ".my_data2")
10:
11: void func3 () {// stored in code snippet. my_data2
12: }
13:
14: #pragma code_seg(pop, r1)
15:
16: void func4 () {// stored in code snippet. my_data1
17: }
7. # pragma pack. Used to change the byte alignment of the compiler. General Usage:
# Pragma pack (n) // set the byte alignment mode of the compiler to n. The value of N is generally 1, 2, 4, 8, and 16. The default value is 8.
# Pragma pack (show) // output the Current byte alignment with warning information
# Pragma pack (push) // put the Current byte alignment into the internal compiler Stack
# Pragma pack (push, 4) // place byte alignment Mode 4 into the internal compiler stack and set the current memory alignment mode to 4
# Pragma pack (POP) // pop up the record at the top of the internal compiler stack and use it as the current memory alignment
# Pragma pack (POP, 4) // bring up the record at the top of the internal compiler stack and use 4 as the current memory alignment
# Pragma pack (POP, R1) // R1 is a custom identifier. The record in the internal compiler is displayed until R1 is displayed and the value of R1 is used as the current memory alignment; if R1 does not exist, when
No operation
Example:
Take the following structure as an example: struct {
Char;
Word B;
Dword c;
Char D;
}
Default structure size in Windows: sizeof (struct) = 4 + 4 + 4 + 4 = 16;
Same as # pragma pack (4)
If it is set to # pragma pack (1), the structure size is: sizeof (struct) = 1 + 2 + 4 + 1 = 8;
If it is set to # pragma pack (2), the structure size is sizeof (struct) = 2 + 2 + 4 + 2 = 10;
When # pragma pack (1): space is saved, but access speed is reduced;
What is the purpose ???
In system communication, such as communication with hardware devices and other operating systems, the consistency between the two parties must be ensured.
8. # pragma comment. Place a comment record in an object file or executable file.
The format is: # pragma comment (comment-type [, "commentstring"]). Here, comment-type is a predefined identifier, which specifies the annotation type, which should beCompiler, exestr, Lib, linker, user.
Compiler: Place the version or name of the compiler to an object file. This option is ignored by linker.
Exestr: It will be canceled in a later version.
Lib: Place a library search record to the object file. This type should be consistent with the library type specified by commentstring (specifying the name and path of the lib to be searched by linker. In the object file, the Library name follows the default search record; linker searches for this library just like you enter this command on the command line. You can set multiple database search records in a source file.
The file appears in the same sequence as in the source file.
If the order of the default and additional libraries needs to be different, use the/ZL compilation switch to prevent the default library from being placed in the object module.
Linker: Specify a connection option, so that you do not need to enter it in the command line or set it in the development environment. Only the following Linker options can be passed to linker:
- /Defaultlib
- /Export
- /Include
- /Manifestdependency
- /Merge
- /Section
(1)/defaultlib: Library
The/defaultlib option adds a library to the list of libraries that link searches for when parsing references. Use the library specified by/defaultlib on the command line and the default library specified in the OBJ file
Library is searched.
Ignore all default libraries (/nodefalib Lib) option to override/defaultlib: Library. If the same library name is specified in both, ignore the Library (/nodefaultlib: Library) option.
/Defaultlib: Library will be rewritten.
(2)/export: entryname [, @ ordinal [, noname] [, Data]
With this option, you can export functions from the program so that other programs can call the function or export data. It is usually defined and exported in DLL.
Entryname is the name of the function or data item to be used by the caller. Ordinal is the index of the exported table. The value ranges from 1 to 65535. If ordinal is not specified, link will allocate one.
The noname keyword only exports the function as the serial number without entryname. The data keyword specifies that the export item is a data item. The data items in the customer program must use extern _ declspec
(Dllimport.
There are three methods for exporting definitions, which are recommended in sequence:
- _ Declspec (dllexport) in source code)
- Exports statement in the. Def File
- /Export specification in link command
All three methods can be used in the same program. Link also creates Import and Export files when generating programs that contain export, unless the. Exp file is used during the generation process.
Link uses the identifier modifier. The identifier is modified by the compiler when the OBJ file is created. If entryname is assigned to the linker as it is not modified (the same as in the source code ),
Will try to match this name. If a unique match name cannot be found, link sends an error message. To assign an identifier to the linker, use dumpbin to get the identifier modification.
Name format.
(3)/include: Symbol
The/include option notifies the linker to add the specified symbol to the symbol table. To specify multiple symbols, enter a comma (,), semicolon (;), or space between symbol names. On the command line, specify/include: symbol for each symbol.
The linker parses the symbol by adding an object containing the symbol definition to the program. This function is useful for adding library objects that are not linked to the program.
The symbols specified with this option will overwrite the removal operation for this symbol through/OPT: ref.
(4)/manifestdependency: manifest_dependency
/Manifestdependency allows you to specify the attribute of the <dependency> segment in the manifest file. /Manifestdependency information can be passed to link in the following two ways:
Run/manifestdependency directly on the command line
# Pragma comment
(5)/merge: From =
The/merge option associates the first segment (from) with the second segment (to) and names the associated segments as the to name.
If the second segment does not exist, link will rename the segment (from) to the to name.
The/merge option is useful for creating vxds and rewriting the segment names generated by the compiler.
(6)/section: name, [[!] {Dekprsw}] [, align = #]
The/section option is used to change the attributes of a segment. When the OBJ file of the specified segment is compiled, the attribute set of the segment is overwritten.
The segments in the portable executable file (PE) are roughly the same as the segments or resources in the new executable file (NE.
Section contains code or data. Unlike the segment, the segment is a continuous memory block with no size limit. The code or data in some segments is directly defined by your program and
Some data segments are created by the chain and Library Manager (lib.exe), and contain important information for the operating system.
The name in the/section option is case sensitive.
Do not use the following names because they are in conflict with standard names. For example,. sdata is used by the RISC platform.
. Arch
. BSS
. Data
. Edata
. Idata
. Pdata
. RDATA
. Reloc
. Rsrc
. Sbss
. Sdata
. Srdata
. Text
. Xdata
Specify one or more attributes for a segment. The attribute is not case sensitive. For a segment, you must specify all the attributes that you want to have. If an attribute is not specified
. If you do not specify R, W, or E, the existing read, write, or executable status will not change.
To get negative meaning for an attribute, you only need to add an exclamation point (!) before the attribute (!).
E: executable
R: readable
W: writable
S: all processes that load the image of this segment are shared.
D: deprecated
K: Non-cacheable
P: Non-Paging
Note that K and P represent negative meanings.
If the segment in the PE file does not have an E, R, or W attribute set, the segment is invalid.
Align = # option allows you to specify an alignment value for a specific segment.
User: place a regular comment to an object file. This option is ignored by linker.
9. # pragma Section. Create a segment.
The format is: # pragma section ("section-name" [, attributes])
Section-name is a required parameter for specifying the name of a segment. The name cannot conflict with the name of the standard section. You can use/section to view the name list of the standard section.
Attributes is optional and used to specify the attributes of a segment. The available attributes are as follows. Multiple Attributes are separated by commas:
Read: readable
Write: writable
Execute: executable
Shared: all processes that load the image of this segment are shared.
Nopage: Non-Paging, mainly used in Win32 Device Drivers
Nocache: Non-cacheable, mainly used in Win32 Device Drivers
Discard: obsolete, mainly used in Win32 Device Drivers
Remove: Non-memory resident, used only in Virtual Device Driver (VxD)
If no attribute is specified, the default attribute is read and write.
After creating a segment, use _ declspec (allocate) to put the code or data in the segment.
For example:
// Pragma_section.cpp
# Pragma section ("mysec", read, write)
Int J = 0;
_ Declspec (allocate ("mysec "))
Int I = 0;
Int main (){}
In this example, the "mysec" section is created and the Read and Write attributes are set. However, J is not included in this section, but in the default data segment, because it does not use _ declspec (allocate)
And I is placed in this section because _ declspec (allocate) is used for declaration.
10. # pragma push_macro and # pragma pop_macro. The former pushes the specified macro into the stack, which is equivalent to temporary storage for future use. The latter pushes the macro at the top of the stack, and the pop-up macro will overwrite the macro with the same name as the current one. For example:
1: #include <stdio.h>
2: #define X 1
3: #define Y 2
4:
5: int main() {
6: printf("%d",X);
7: printf("\n%d",Y);
8: #define Y 3 // C4005
9: #pragma push_macro("Y")
10: #pragma push_macro("X")
11: printf("\n%d",X);
12: #define X 2 // C4005
13: printf("\n%d",X);
14: #pragma pop_macro("X")
15: printf("\n%d",X);
16: #pragma pop_macro("Y")
17: printf("\n%d",Y);
18: }
Output result:
1
2
1
2
1
3