Preprocessing is done before the source code is translated into machine instructions. The preprocessing functions mainly include macro definition, file inclusion and conditional compilation. These preprocessing actions occur during the compiler process, and they modify the program's statements, but do not interfere with the execution of the program.
The ANSI standard-defined C language preprocessor includes the following commands:
Instruction use
#include contains a source code file
#define Defining macros
#undef to cancel a defined macro
#if if the given condition is true, compile the following code
#ifdef If the macro is already defined, compile the following code
#ifndef if the macro is not defined, compile the following code
#elif if the previous # if given condition is not true and the current condition is true, compile the following code
#endif end an # if ... #else条件编译块
#error stop compiling and display an error message
#else slightly
#line directives can change the file number and line number used by the compiler to indicate warnings and error messages.
#pragma set the state of the compiler or instruct the compiler to complete some specific actions.
#pragma指令稍复杂, the format is generally: #pragma para, the following see some of the parameters commonly used #pragma directives.
(1) Message parameter
Message parameter to output the appropriate information in the Compile Information Output window.
This is very important for the control of source code information. It is used in the following ways:
#pragma message ("text")
When the compiler encounters this instruction, it prints the message text in the compilation Output window.
When we define a number of macros in the program to control the source code version, we may forget that we have the correct settings for these macros.
At this point we can use this command to check at compile time. Let's say we want to determine if we have a macro that defines _x86 somewhere in the source code.
You can use the following method:
#ifdef _x86
#pragma message ("_x86 macro activated!")
#endif
After we have defined the _X86 macro, the application will display the "_86 macro activated!" in the compiled Output window at compile time.
We will not scratching because we do not remember some of the specific macros we have defined.
(2) Another pragma parameter that is used more is code_seg
Formats such as:
#pragma code_seg (["Section-name" [, "Section-class"]]
It is able to set the code snippet where the function code is stored in the program, which is used when we develop the driver.
(3) #pragma once (more commonly used)
As long as this command is added at the very beginning of the header file, it is guaranteed that the header file will be compiled once, and this instruction is actually in VC6.
But considering compatibility doesn't have much to do with it.
(4) #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,
However, if all header files are precompiled and may account for too much disk space, use this option to exclude some header files.
Sometimes there are dependencies between units, such as cell A depends on unit B, so unit B is compiled before unit A.
You can use #pragma startup to specify the compilation priority, if the #pragma package (smart_init) is used,
BCB will be compiled according to the priority size.
(5) #pragma resource "*.DFM"
Indicates that the resources in the *.DFM file are added to the project. Include form in *.DFM
The definition of the appearance.
(6) #pragma warning (disable:4507; once:4385; error:164)
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 the 164th warning message as an error.
This pragma warning also supports the following formats:
#pragma warning (push [, N])
#pragma warning (POP)
Here n represents a warning level (1---4).
#pragma warning (push) to save an existing warning state for all warning messages.
#pragma warning (push, N) holds the existing warning state for all warning messages and sets the global warning level to N.
#pragma warning (pop) pops the last warning message to the stack and cancels all changes made between the stack and the stack. 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, all warning messages (including 4705,4706 and 4707) are re-saved.
(7) #pragma comment (...)
This directive 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. Such as:
#pragma comment (lib, "Comctl32.lib")
#pragma comment (lib, "Vfw32.lib")
#pragma comment (lib, "Wsock32.lib")
Each compiler can use the #pragma directive to activate or terminate some of the compilation features supported by the compiler.
For example, for the Loop optimization feature:
#pragma loop_opt (ON)//Active
#pragma loop_opt (off)//termination
Sometimes, there are functions in the program that cause the compiler to emit warnings 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
The function generates a warning message with a unique signature of 100, so that the warning can be temporarily terminated.
Each compiler has a different implementation of #pragma, which is effectively in a compiler that is almost invalid in another compiler. Can be viewed from the compiler's documentation.
#pragma pack and memory alignment issues
Many real computer systems restrict the location of basic types of data in memory, and they require that the value of the first address of the data be a number k
(usually it is a multiple of 4 or 8), which is called memory alignment, and this k is called the number of Zimo (alignment modulus) for that data type.
The Microsoft C compiler (Cl.exe for 80x86) under the Win32 platform uses the following alignment rules by default:
The Zimo number of any basic data type T is the size of T, which is sizeof (t). For example, for a double type (8 bytes),
The address that requires this type of data is always a multiple of 8, and the Char type data (1 bytes) can start at any address.
GCC under Linux pursues a different set of rules, with any 2-byte data type (such as short) having a Zimo number of 2, and all other data types that are more than 2 bytes in size
(for example, long,double) all use 4 for the number of Zimo.
ANSI c specifies that the size of a struct type is the sum of the size of all its fields and the size of the fill area between fields or the end of a field.
The fill area is the extra space allocated to the struct for the structure field to meet the memory alignment requirements. So what are the alignment requirements of the structure itself?
Yes, the ANSI C standard specifies that the alignment requirements of the struct type cannot be more stringent than the one that is most stringent in all of its fields.
How to use the alignment options in C + +
The compilation options in VC6 are/zp[1|2|4|8| /ZP1 represents a 1-byte boundary alignment, and the corresponding/ZPN represents an n-byte boundary alignment.
N-byte boundary alignment means that the address of a member must be arranged on an integer-multiple address of the member's size or an integer-multiple address of N, taking the minimum value from them.
That is
Min (sizeof (member), N)
In fact, a 1-byte boundary alignment also indicates that there are no voids between struct members.
The/ZPN option is applied to the entire project, affecting all the constructs that participate in the compilation.
To use this option, you can open the Project Properties page in VC6, C + + pages, select the code Generation category, and select the struct member alignment.
To use the alignment options specifically for certain structure definitions, you can use the #pragma pack compilation directives:
(1) #pragma pack ([n])
This instruction specifies the compact alignment of the structure and the union members. While the structure of a complete conversion unit and the combined compact alignment are set by the/zp option.
Compact alignment is set in the data Description layer with pack compilation instructions. The compilation instruction takes effect at the first structure or joint description after it appears.
The compilation indicates that the definition is invalid.
When you use #pragma pack (n), here n is 1, 2, 4, 8, or 16.
Each struct member after the first struct member is stored within a smaller member type or an n-byte boundary.
If you use the #pragma pack without parameters, the struct member is compact to the value specified with/zp. The default/zp compact value is/ZP8.
(2) The compiler also supports the following enhanced syntax:
#pragma pack ([[[{push | pop},] [identifier,]] [n])
If different components use the pack compilation instructions to specify different compact alignments, this syntax allows you to combine program components into a single unit of conversion.
Each occurrence of the pack compilation indicator with the push parameter stores the current compact alignment in an internal compiler stack.
The parameter table for compiling instructions is read from left to right. If you use push, the current compact value is stored;
If you give a value of N, the value becomes the new compact value. If you specify an identifier, that is, you select a name,
The identifier will be associated with this new compact value.
Each occurrence of a pack compilation indicator with a POP parameter retrieves the value of the top of the internal compiler stack and causes the value to be a new compact alignment value.
If you use a pop parameter and the internal compiler stack is empty, the compact value is the value given by the command line, and a warning message is generated.
If you use pop and specify a value of N, the value becomes the new compact value. If you use P O p and specify an identifier,
All values stored in the stack are removed from the stack until a matching identifier is found, and the compact value associated with the identifier is also removed from the stack.
Also this compact value that exists only before the identifier into the stack becomes the new compact value. If no matching identifiers are found, the
A compact value that will be set using the command line, and a first level warning will be generated. The default compact alignment is 8.
The new enhancements to the pack compilation instructions let you write a header file that ensures that before and after encountering the header file
The compact value is the same.
(3) Stack memory alignment
The alignment of the stack in VC6 is not affected by the structure member alignment options. It is always aligned and aligned on a 4-byte boundary.
c--preprocessing directives