#Pragma是预处理指令, its role is to set the state of the compiler or instruct the compiler to perform certain actions.
#Pragma指令对每个编译器给出了一个方法, to give the host or operating system proprietary features, while maintaining complete compatibility with the C and C + + languages. By definition, the compilation instructions are proprietary to the machine or operating system and are different for each compiler.
The format is generally: #Pragma Para
Where para is the parameter, here are some common parameters.
(1) the message parameter. the message parameter is my favorite parameter, it can output the corresponding information in the Compiling Information Output window, which is very important for the control of the source code information. It uses the following methods:
#Pragma messages (Message text)
When the compiler encounters this instruction, it prints the message text in the Compile Output window. When we define a lot of macros in the program to control the source version of the code, we are likely to forget that there are no correct settings for these macros, at this time we can use this instruction at compile time to check. Let's say we want to determine if we've defined _x86 somewhere in the source code. This macro can be used in the following ways
#ifdef _x86
#Pragma message ("_x86 macro activated!")
#endif
When we define the _x86 macro, the application displays in the compiled Output window at compile time "_
X86 macro activated! ". We don't scratching because we don't remember some of the specific macros we've defined.
(2) Another pragma parameter that is used more is code_seg.
Format such as:
#pragma code_seg ([\section-name\[,\section-class\]])
It can set code snippets that are stored in the function code in the program, and the #pragmacode_seg with no section-name string can be reset at the start of the compilation and used when we develop the driver.
(3) #pragma once (more commonly used)
Adding this instruction at the beginning of the header file ensures that the header file is compiled once, and this instruction is actually available in the VC6, but there is not much use of it, given the compatibility.
(4) #pragma hdrstop indicates that the precompiled header file ends here, and the following header file is not precompiled.
BCB can precompile header files to speed up the link, but if all header files are precompiled and may take up too much disk space, use this option to exclude some header files. Sometimes there are dependencies between units, such as unit a dependent B, so cell B is compiled before cell a. You can specify the compilation priority with #pragma, and if the #pragma package (smart_init) is used, BCB compiles according to the priority size.
(5) #pragma resource \*.dfm\ indicated that the resources in *.DFM file should be added to the project.
The *.DFM includes a definition of the form's appearance.
(6) #pragma warning (disable:4507 once:4385; error:164)
Equivalent to:
#pragma warning (disable:4507 34)//Do not display warning messages 4507 and 34th
#pragma warning (once:4385)//No. 4385 warning message is only reported once
#pragma warning (error:164)//Put warning number 164th as a mistake.
At the same time this pragma warning also supports the following format:
#pragma warning (push [, N])
#pragma warning (POP)
Here n represents a warning level (1---4).
#pragma warning (push) saves an existing warning state for all warning messages.
#pragma warning (push, N) saves the existing warning state of all warning messages and warns the global
The level is set to N.
#pragma warning (pop) pops the last warning message to the stack, between the stack and the stack.
All changes are canceled. For example:
#pragma warning (push)
#pragma warning (disable:4705)
#pragma warning (disable:4706)
#pragma warning (disable:4707)
//.......
#pragma warning (POP)
At the end of this code, save all the warning messages (including 4705,4706 and 4707).
(7) pragma comment (...)
This instruction places a note record into an object file or executable file.
The commonly used LIB keyword can help us to connect to a library file.
(8) Changing the byte alignment of the C compiler via #pragma pack (n)
In C, a structure is a composite data type whose constituent elements can be variables of basic data types (such as int, long, float, and so on) or data units of some composite data types (such as arrays, structs, unions, etc.). In a structure, the compiler allocates space for each member of the structure according to its natural bounds (alignment) condition. Each member is stored sequentially in memory in the order in which they are declared, with the address of the first member the same as the address of the entire structure.
For example, the following structure member space allocations:
struct test
{
Char X1; Offset address is 0
Short x2;//offset address is [2,3]
Float x3;//offset address is [4,7]
Char x4; Offset address is 8
};
The first member of the structure, X1, has an offset address of 0, which occupies the 1th byte. The second member, X2, is of type short and its starting address must be 2 bytes in bounds, so the compiler populates a null byte between X2 and X1. The third member of the structure, X3, and the fourth member X4 happen to be on their natural alignment address, and no additional padding bytes are required before them. In the test structure, the member X3 requires a 4-byte pair, which is the largest bounding unit required by all members of the structure, so the natural boundary condition of the test structure is 4 bytes, and the compiler populates 3 empty bytes after the member X4. The entire structure occupies 12 bytes of space. Change the C compiler's
Default byte alignment By default, the C compiler assigns each variable or data element according to its natural boundary condition
Space. Generally, you can change the default boundary condition by using the following methods:
· Using pseudo-directive #pragma pack (n), the C compiler is aligned according to n bytes.
· Use the pseudo Directive #pragma pack () to cancel the custom byte alignment.
In addition, there are also the following ways:
· __attribute ((aligned (n)) to align the member of the structure to the N-byte natural boundary. If the length of a member in the structure is greater than N, it is aligned according to the length of the maximum member.
· __ATTRIBUTE__ ((packed)), cancels the optimized alignment of the structure during compilation, and aligns to the actual number of bytes occupied.
The above n = 1, 2, 4, 8, 16 ... The first approach is more common.
Application examples
In network protocol programming, data packets of different protocols are often processed. One way is through the pointer offset
method to get a variety of information, but this is not only complex programming, but once the protocol changes, the program changes
Also more trouble. After understanding the compiler's allocation of structural space, we can fully utilize this
A feature defines its own protocol structure by accessing the members of the structure to obtain various information. Doing so,
Not only does it simplify programming, but even if the protocol changes, we just need to modify the definition of the protocol structure.
Other procedures need not be modified, save time and effort. The following is an example of the TCP protocol header, which describes how to define a protocol structure.
Its protocol structure is defined as follows:
#pragma pack (1)//is aligned in 1-byte mode
struct Tcpheader
{
Short srcport; 16-bit Source port number
Short dstport; 16-bit Destination port number
int Serialno; 32-bit serial number
int ackno; 32-digit Confirmation number
unsigned char haderlen:4; 4-Digit Header length
unsigned char reserved1:4; Keep 4 bits in 6 digits
unsigned char reserved2:2; Keep 2 bits in 6 digits
unsigned char urg:1;
unsigned char ack:1;
unsigned char psh:1;
unsigned char rst:1;
unsigned char syn:1;
unsigned char fin:1;
Short windowsize; 16-bit window size
Short tcpchksum; 16-bit TCP test and
Short Urgentpointer; 16-bit emergency pointer
};
#pragma pack ()//Cancel 1-byte alignment
The length of the alignment specified #pragma pack, and the actual rules used are:
Structure, union, or class of data members, the first place where the offset is 0, the alignment of each data member in the future, the value specified by the #pragma pack and the length of the data member itself, compared to the smaller one.
That is, when the value of the #pragma pack equals or exceeds the length of all data members, the size of the value will have no effect.
The alignment of the structure as a whole is carried out according to the size of the largest data member in the structure and the specified value of the #pragma pack.
Specify the library to use for the connection
For example, when we connect with the WSock32.lib, you can certainly take the trouble to add it to your project. But I think it's more convenient to use the #pragma designator to specify the library to connect to:
#pragma comment (lib, "WSock32.lib")