#pragma预处理命令
The most complex preprocessing directives #pragma可以说是C + +, the following are the most commonly used #pragma directives:
#pragma comment (lib, "XXX.lib")
Indicates that the link XXX.lib this library, and is written in the project settings XXX.lib the same effect.
#pragma COMMENT (linker, "/entry:main_function")
Represents the specified linker option/entry:main_function
#pragma once
Indicates that this file is included only once
#pragma warning (disable:4705)
Indicates a masking warning 4705
Each execution of C and C + + programs supports some unique features of the host or operating system on which it resides. For example, some programs require precise control over the area of memory in which the data resides or control a letter
The number of received parameters. #pragma为编译器提供了一种在不同机器和操作系统上编译以保持C和C + + is a fully compatible method. #pragma是由机器和相关的操作系统定义
, which is usually different for each compiler.
If the compiler encounters a pragma instruction that it does not know, it will give a warning message and then continue compiling. The following directives are recognized by the compilers of Microsoft C and C + +: 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,warning. Among them conform,init_seg,
Pointers_to_members,vtordisp is supported only by the C + + compiler.
The following is a detailed explanation of commonly used pragma directives.
1. #pragma once. The guaranteed file is only included once, it is based on the disk file, and the #ifndef is macro-based.
2. #pragma warning. Allows selective modification of the compiler's warning message behavior. There are the following uses:
#pragma warning (disable:4507; once:4385; error:164) is equivalent to:
#pragma warning (disable:4507 34)//Do not display 4507 and 34th warning messages
#pragma warning (once:4385)//No. 4385 warning information is reported only once
#pragma warning (error:164)//Put 164th warning message as an error
#pragma warning (default:176)//Reset the compiler's 176th warning behavior to the default state
This pragma warning also supports the following format, where n represents a warning level (1---4):
#pragma warning (push)//save an existing warning status for all warning messages
#pragma warning (push,n)//Save the existing warning status for all warning messages 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 4705,4706 and 4707) are restored.
3. #pragma hdrstop. This means that the precompiled header file ends, and the subsequent header files are not precompiled. BCB can precompile the header file to speed up the link, but if all the header files are in
The row precompilation may also account for too much disk space, so use this option to exclude some header files.
4. #pragma message. Outputs the specified text information in a standard output device without ending the program running. Use the following:
#pragma message (the "text"). When the compiler encounters this instruction, it prints the message text in the compilation Output window.
5. #pragma data_seg. Typically used in DLLs, it is possible to set initialization variables in the program in the data segment where the obj file resides. If no argument is specified, the initialization variable is placed in the default number
According to paragraph. data, the following usage is used:
1: #pragma data_seg ("shared") //defines the data segment "shared", with two variables A and b
2:int a = 0; stored in data segment "Shared"
3:int b; stored in the data segment ". BSS" because there is no initialization
4: #pragma data_seg () //Indicates the end of data segment "Shared", the line code is optional
It is important to initialize variables specifically, otherwise the compiler will place them in normal uninitialized data segments instead of in shared. If the variable b above is actually placed in the uninitialized number
According to paragraph. BSS.
1: #pragma data_seg ("Shared")
2:int j = 0; stored in data segment "Shared"
3: #pragma data_seg (push, Stack1, "Shared2")//define data segment Shared2 and assign the record to 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) //POPs the record from the internal compiler stack until the stack1 pops up, and if there is no stack1, no action is made
6:int m = 0; stored in the data segment "Shared", if there is no such pop segment, then the variable will be stored in the data segment "Shared2"
6. #pragma code_seg. It is able to set the code snippet where the function in the program resides in the obj file. If you do not specify a parameter, the function is placed in the default code snippet. Text, with the following usage:
1:void func1 () { //default is stored in the code snippet. Text
2:}
4: #pragma code_seg (". My_data1")
6:void Func2 () { //stored in code snippet. my_data1
7:}
9: #pragma code_seg (push, R1, ". My_data2")
11:void func3 () { //stored in code snippet. My_data2
12:}
: #pragma code_seg (pop, R1)
16:void Func4 () { //stored in code snippet. my_data1
17:}
7. #pragma pack. Used to change the byte alignment of the compiler. General usage is:
#pragma pack (n)//Set the compiler's byte alignment to n,n with a value of 1, 2, 4, 8, 16, typically 8 by default
#pragma pack (show)//The current byte alignment output as a warning message
#pragma pack (push)//puts the current byte alignment into the internal compiler stack
#pragma pack (push,4)//Put byte alignment 4 into the internal compiler stack and set the current memory alignment to 4
#pragma pack (POP)//eject the record at the top of the internal compiler stack and use it as the current memory alignment
#pragma pack (pop,4)//Eject 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 that pops the record in the internal compiler until it pops up R1, and the value of R1 as the current memory alignment; If R1 does not exist, when
Do not do any action
An example:
take the following structure as an example: struct {
Char A;
WORD b;
DWORD C;
Char D;
}
In Windows default structure size: sizeof (struct) = 4+4+4+4=16;
Same as #pragma pack (4)
if set to #pragma pack (1), the structure size: sizeof (struct) = 1+2+4+1=8;
If set to #pragma pack (2), the structure size: sizeof (struct) = 2+2+4+2=10;
At #pragma pack (1): The space is saved, but the access speed is reduced;
What's the use???
In the system communication, such as communication with the hardware device, and other operating systems to communicate, etc., must ensure the consistency of both parties.
8. #pragma comment. Place a note record in an object file or an executable file.
The format is: #pragma comment (comment-type [, "commentstring"]). Where Comment-type is a predefined identifier that specifies the type of annotation and should be one of the compiler,exestr,lib,linker,user .
compiler: Place the compiler's version or name into an object file, which is ignored by linker.
exestr: In future versions will be canceled.
Lib: Place a library search record into the object file, which should match the library type specified by commentstring (specifying the name and path of the LIB linker to search). In the object file, the name of the library follows the default search record; linker search this library as you would enter this command at the command line. You can set up multiple library search records in one source file, in the obj
The order in which they appear in the file is the same as the order in which they appear in the source file.
If the order of the default libraries and additional libraries is different, use the/zl compile switch to prevent the default libraries from being placed in the object module.
linker: Specify a connection option so that it does not have to be entered at the command line or set 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 resolving references. The library specified in/defaultlib after the library specified on the command line and the default specified in the obj file
library before being searched.
Override/defaultlib:library for all default library (/NODEFAULTLIB) options. If you specify the same library name in both, the Ignore library (/nodefaultlib:library) option
The/defaultlib:library will be rewritten.
(2)/export:entryname[, @ordinal [, Noname]][,data]
With this option, you can export functions from a program so that other programs can call the function, or you can export data. Exports are typically defined in a DLL.
EntryName is the name of the function or data item to be used by the calling program. Ordinal is the index of the exported table, the value range is 1 to 65535, and if no ordinal is specified, link assigns one.
The Noname keyword only exports the function as an ordinal, without entryname. The data keyword specifies that the export item is an item. Data items in the client program must be in extern __declspec
(dllimport) to declare.
There are three ways to export definitions, followed by the recommended order of use:
- __declspec (dllexport) in source code
- Exports statements in. def files
- The/EXPORT specification in the link command
All three of these methods can be used in the same program. Link also creates an import library when the program that contains the export is generated, unless the. exp file is used during the build process.
Link uses the decorated form of an identifier. The compiler modifies the identifier when it creates the obj file. If EntryName is assigned to the linker in its unmodified form (as in the source code), the link
Will attempt to match the name. If a unique matching name cannot be found, link issues an error message. When you need to assign an identifier to the linker, use the DUMPBIN tool to get the adornment of the identifier
Name form.
(3)/include:symbol
The/INCLUDE option notifies the linker to add the specified symbol to the symbol table. To specify more than one symbol, type a comma (,), semicolon (;) or space) between the symbol names. On the command line, you specify one/include:symbol for each symbol.
The linker parses the symbol by adding the object that contains the symbol definition to the program. This feature is useful for adding library objects that are not linked to the program.
The symbol specified with this option overrides the Remove action on the symbol through/OPT:REF.
(4)/manifestdependency:manifest_dependency
/manifestdependency allows you to specify the properties of the <dependency> segment located in the manifest file. /manifestdependency information can be passed to link in one of the following two ways:
Run/manifestdependency directly on the command line
by #pragma comment
(5)/merge:from=to
The/MERGE option unions the first segment (from) with the second segment (to) and names the joined segment to the name of to.
If the second segment does not exist, link renames the segment (from) to the name of the to.
The/merge option is useful for creating VxDs and overriding the compiler-generated segment names.
(6)/section:name,[[!] {DEKPRSW}] [, align=#]
The/SECTION option is used to change the properties of a segment, overriding the attribute set of a segment when the obj file where the specified segment is compiled.
The Segments (section) in the portable executable (PE) are roughly the same as the sections (segment) or resources in the new executable file (NE).
The segment (section) contains code or data. Unlike a section area (segment), a segment (section) is a contiguous block of memory with no size limit. Some sections of code or data are directly defined by your program and
, and some data segments are created by the linker and Library Manager (lib.exe) and contain information that is important to the operating system.
The name in the/SECTION option is case-sensitive.
Do not use the following names because they conflict with the standard name, 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 properties for the segment. Properties are not case sensitive. For a segment, you must specify the properties that you want it to have, and if an attribute is not specified, it is considered not to have this genus.
Of If you do not specify R,w or E, the existing read, write, or executable state will not change.
To negate a property, simply add an exclamation point (!) to the property.
E: Executable
R: Readable
W: Writable
S: All processes that are loaded into the mirror of the segment are shared
D: Can be discarded
K: Non-cacheable
P: Non-paged
Note that K and P are negative meanings.
The segment in the PE file is not valid if there is no e,r or W attribute set.
Align= #选项让你为一个具体的段指定对齐值.
User: Place a general comment into an object file, which is ignored by linker.
9. #pragmasection. Create a segment.
The format is: #pragma section ("Section-name" [, Attributes])
Section-name is a required option for specifying the name of the segment. The name cannot conflict with the name of the standard paragraph. Use/section to view a list of the names of standard segments.
Attributes is an option that specifies the properties of a segment. The available properties are as follows, separated by commas (,) between multiple attributes:
READ: Readable
Write: Writable
Execute: Executable
Shared: All processes that are loaded into the mirror of the segment are share
Nopage: Non-paged, primarily for WIN32 device drivers
NoCache: Non-cacheable, primarily for Win32 device drivers
Discard: Obsolete, primarily used in device drivers for Win32
Remove: Non-memory resident, only in virtual device driver (VxD)
If no attribute is specified, the default property is read and write.
After you create a segment, you also use __declspec (allocate) to put code or data into segments.
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 segment "Mysec" is created, and the Read,write property is set. However, J is not put into the paragraph, but is placed in the default data segment because it does not use __declspec (allocate) to enter the
And I was placed in the paragraph because it was declared with __declspec (allocate).
#pragma push_macro and #pragma pop_macro. The former pushes the specified macro into the stack, which is equivalent to temporarily storing it for later use, and the latter pushes the top macro out of the stack, and the macro that pops up overrides the current name. For example:
1: #include <stdio.h>
2: #define X 1
3: #define Y 2
5:int Main () {
6:printf ("%d", X);
7: printf ("\n%d", Y);
8: #define Y 3 //C4005
9: #pragma push_macro ("Y")
: #pragma push_macro ("X")
11:printf ("\n%d", X);
: #define X 2 //C4005
13:printf ("\n%d", X);
: #pragma pop_macro ("X")
: printf ("\n%d", X);
: #pragma pop_macro ("Y")
: printf ("\n%d", Y);
18:}
Output Result:
1
2
1
2
1
3
#pragma预处理命令