Writing and debugging of VC code

xiaoxiao2021-03-06  54

Zhenxizhen

Writing and debugging of VC code

The design of a program for easy debugging VC code is to avoid errors, first start with a good design. For program design, you need to take into account two features of the program: 1 Simplicity Most common errors come from unnecessary complex ingredients in programming. A good design should reflect the requirements of the problem itself, without having to add unnecessary features to deliberately pursue "satisfying future needs". In fact, simple and elegant design causing future needs than those complex design. 2 coupling coupling (decoupling) is used to measure the dependence between different objects. Loose coupling procedures are easy to understand and implement, easy to test and maintain, and this program contains miscible, and error is also easier to discover and clear. Second programming style programming style is personal problem, there is a lot of randomness. A good programming style not only makes the code easy to understand, but also easy to debug. Good programming style includes: 1 clear writing code If there is no need, try not to use the advanced features in the language because these features are not easy to understand and debug. Writing code is not easy to make mistakes using most of the programmers understand the language ingredients and easy to understand and maintain. 2 Writing a structure Good code When the program crashes, the most basic debug information that can be obtained is the source code file, the line number of the problem and a call stack. The calling stack is the most helpful part of the debugger, which provides the context that appears, which is a function call sequence with parameters. The better the code structure you write, the more information you can give you. 3 Use a good identifier a good name to make your code easier to understand and maintain. The popular Hungarian NOTATION actually combines the meaning of the identifier and the expression method. Now, Hungarian nomenclature has a lot of limitations. The Hungarian nomenclature is too valued. The expression of a variable is incomplete. It is actually not delivered to how much useful information, which makes code difficult to read, difficult to maintain. A good named tradition is a scope of the variable to check its definition when needed, and clearly indicate that a variable is a global, partial or member data. Dependency variables are more useful and reliable than dependent Hungarian prefix. A good name can generalize the meaning of the entity represented by the identifier in a usual language. When selecting classes, functions, and variables, you can consider the following principles: Take a simple descriptive name, good names can summarize the meaning of this identifier representative. Avoid shorthabing, short-handed identifier is difficult to read and memorize, try to use a complete word of mixed case. Avoid the text of the similarity to avoid confusion. Avoid adopting general or random names, but should use the actual name. To take a bitmap button from the button class, take a cbitmapbutton instead of CMYButton. 4 Use a simple statement to write multiple statements in a line. But debugging is facing, too complicated, difficult to debug. Therefore, from the perspective of debugging, each statement should be in a row. 5 Use a unified arrangement unified arrangement to make the class, variable definitions and statements more apparent. 6 Bring the writing clearly. You don't necessarily remember the priority and combination of various operators, and use excess parentheses does not affect the compiled code. So if you can't determine if you need parentheses, add it. 7 Use good comments Use a good comment to make your code difficult to make mistakes, and make it easy for other programmers to read and make it easy to understand and maintain.

Items that should be noted when writing procedures 1 Take advantage of the characteristics of VC to make full use of the characteristics of VC compiler: (1) instead of #define with constant; (2) replace #define with ENUM to create constants Collection; (3) instead of #define with an inline function; these three techniques are used in C instead of C pre-processed. The problem with pretreatment is that the compiler does not know if the compiler does something made by the preparation, so it cannot be used to check the errors and inconsistent places. The pre-processed name is not in the symbol table, so it cannot be used to check the pretreatment constant. Similarly, the preprocessing macro is compiled and cannot be tracked with debug tools. The compiler fully understands the const, enum, and inline statements, so that the problem will be warned when compiling. But preprocessing plays an important role in many debuggers. Debug code often needs to get different behaviors from non-debug code, and the most effective way is to let preprocesses create different code for debugging. (4) Instead of Malloc and Free; in terms of creating objects, types of security and flexibility. Use new / delete better than Malloc / Free. In addition, New can be overloaded, providing greater flexibility. (5) Instead of STDIO with an input and output stream (iostreams). Use C input and output streams (<< and >>) without using C standard input and output libraries (PrintF / Sprintf and Scanf / SSCANF) are conducive to security and scalability. From the perspective of debugging, the biggest problem with standard input and output functions is that the compiler cannot detect any type detection on the control flow parameters, and any problem with the input and output stream can be detected at compile. 2 Use the header to declare all shared external symbols in the header file, and reserve the parameter name in the function prototype. Put all shared definitions in the header file, do not see the extern keyword in the .cpp file. 3 Initialization variables must initialize them before using variables. Use variables will definitely generate errors before initialization. You usually do not need to initialize the object, and the pair of data should be initialized in the constructor. It must be explicitly initialized for the arrays and data structures allocated in the stack and the stacks. For objects, each need to initialize the data should be initialized. Because the use of variables are checked by an optimizer, the local variables that are not initialized are detected, and the release version is better than the debug version. 4 Use Boolean Expression C Boolean type: Bool, value True and False, size is one byte. Windows programs typically use the BOOL type. Definitions as follows: typedef int bow; #define false 0 #define true 1 In C , a Boolean expression is false, and the other is true. Therefore, the Boolean expression should check if the counterfeit rather is true. 5 When using the handle and the pointer to initialize a pointer, or let it point to an effective memory address, or set to 0 (empty pointer), avoid the pointer to the invalid address. Recycling this pointer when the object refers to the pointer, and processes it when the pointer is released before the pointer is released. The processing of the handle is the same as the pointer. 6 Use the reference instead of the pointer to do the parameters for the pointer to perform a function, which is very flexible, but it is also easy to forget to initialize the pointer.

The reference is an alias of the object, it must be associated with a valid object, there is no reference to empty and no initialization. When you receive a reference parameter in a function, it is certain that this is a valid object. The quote for the program is more robust than the parameters for the pointer. 7 Force Type Conversion (CAST) Mandatory Type Conversion of Data Types, the corresponding constructor or conversion function will be called to create a new type of temporary object. The correct type conversion of the pointer eliminates a compilation error, but does not change the pointer. Forced type conversion destroys the functionality of the compiler for type inspection, which is the most effective mechanism for compilers to find errors. To ensure security, each forced type conversion requires manual type check. To try to avoid mandatory type conversion, you can: avoid using polymorphism data types; use a more wide base class; provide special access functions; let the compiler implicitly handled type conversion. 8 Use constructor and destructive function constructor to allocate memory, create resources, or open files, which are not always successful. The constructor does not return a value, and there is no way to display an error directly. A common method (used in many MFC classes) is to create object creation into two steps: first step, let constructor initialize the object in a way that will not be wrong; second step, let some initialization functions (such as INIT or OPEN is complete, this step may be wrong. Another method is to use an exception in the constructor: the first step is initialized in a way that does not have an error; the second step is to initialize the object with the code that may be erroneous in the TRY segment; the third step is processed in the CATCH code abnormal. If an exception occurs, the allocated resource will be cleared in the constructor and throw an exception again. A key detail of exception handling is an exception thrown during the stack to terminate the entire application. When processing an exception, the destructive function is often called, so the destructive function is easily error, and must ensure that the exception of the destructive function is processed in the destructor. To ensure that the analytical function of the base class is a virtual function. In this way, even if the object is a pointer to the base class, the secting function of the derived class will also be called. Otherwise, resource leaks will be caused. Using debug statements in the VC program To better debug program, you can use the following methods: Use assertions, use tracking statements, use exceptions and return values. 1. Aspiration 1, basic concept assertion is a simple and effective technique that makes errors to expose themselves. They help you find errors earlier, making the entire debugging process efficient. As a Boolean trial statement, it is used to detect whether the value of a certain condition is always true when the program is running normally. It allows errors to expose in front of the programmer at runtime. The biggest advantage of using assertions is that you can discover errors in a place where the wrong origin is more resolved. As an assertion: assertion is used to find out the runtime error, and the discovered error is about program implementation. The Boolean expression in asserts displays an effectiveness of an object or state rather than the correctness. As an assertion that exists only in the debug version after conditioning, not the release version. As an assertion that cannot contain program code. . As an assertion to provide information about the programmer rather than the user. The most fundamental advantage of using assertions is to automatically discover the errors generated by many rules, but assertions cannot find all errors. As an assertion is the effectiveness of the program, not the correctness, and the error can be limited to a limited range by assertion. When assertion is fake, activation When the debugger displays the error code, you can use the call stack command to check the context, a small amount of related parameters, and the contents of the DEBUG table in the stack, usually, the cause of the assertion failed. _ASSERTE Macro (belonging to C running time library) can also display a failure assertion when asserting fails. Let's discuss the assertions in the MFC library.

2, the assertion in the MFC library (1) Assert (Boolean expression) is best to choose an ASSERT macro when using MFC, and its advantage is that an assertion failure message box can be displayed even if a WM_QUIT message appears. (2) Verify (Boolean expression) Verify macro is retained in the published version. The Verify macro simplifies the check of the function return value, generally used to check the return value of the Windows API. Because the Boolean expression in Verify is reserved in the release version, it is best not to use this macro to implement the full separation of the program code and debug code. (3) Assert_Valid (Pointer to the COBJECT Delicate Class Object) Assert_Valid macro determines whether the pointer to the COBJECT derived class object is valid by calling the overloaded AssertValid function. No matter when you get an object from the COBJECT derived class, you should call the Assert_Valid macro before doing anything to do this object. (4) Assert_kindof (class name, pointing to the cobject derived class object) This macro is used to verify that the pointer pointing to the COBject derived class object is derived from a special class, call the assert_valid macro before calling it. It is only available in a very special occasion, such as the object type problem that the compiler may miss. In addition, there are two species of Assert macros without official files: assert_pointer, assert_null_or_pointer (pointer, pointer type). 3, when using assertions to view the assertion as a simple manufacturing fence, this fence allows the error to expose when they pass themselves. Check the input of the function. Check the output of the function. Check the current status of the object. Adhere to the rationality and consistency of logical variables. Check the non-variable public member function in the class requires more comprehensive assertions than the private and protected member functions. Use the assertion inappropriately causes errors. As an assertion should detect a state that will never appear when the program is running normally. As an assertion is used to reveal the wrong, not to correct the runtime error. 4. As an assertion and defensive programming asserts to reveal the runtime error (debug version) when debugging, and the defensive programming user is running the program (release), when an unexpected situation occurs The program can still continue to work. In fact, the defensive programming requires the program to return a "secure" value when detecting accidents (such as the Boolean function returns false, pointer and handle return null value), an error code or throw an exception to solve the problem. Specific defensive programming techniques include: processing invalid function parameters and data, the program failed, check the error code returned by the critical function, and the processing exception. Standards that require defensive programming include: erroneous input data, memory, or hard disk space is not enough, can not open a file, the external device can not access, the network connection is not or even in the program, the purpose is to maintain the operation of the program . If your program is defensive, don't forget to use assertions. If you use the assertion, don't forget the defensive programming. These two techniques are preferably used together. Second, tracking statements 1, the basic concept tracking statement enables the program to perform and make the programmer to view variable values. They provide a program for observation and independently of an interactive debugger, but most features are commonly used to supplement the information provided by the debugger. In VC, tracking messages typically output the Debug tag in the output window, or re-output it into a file. The features of the tracking statement are as follows:. Tracking statements are used to report important running events in the code. The compilation of the tracking statement is usually conditional and only exists in the debug version, and is not compiled in the publish version. Tracking statements cannot include program code or have indirect effects on program code. The purpose of the tracking statement is to provide information to the programmer instead of to the user.

The tracking statement is also a debug statement, which can execute the program, and programmers can view the variables in the run. Tracking statements are very effective for programs that use interactive debuggers. The difference between tracking statements and assertions is as follows:. Tracking statements are unconditional, assertions are conditional Boolean statements. The tracking statement is used to display the program execution and variable values, not directly displaying bugs, asserts to show BUG. The tracking statement outputs the information to the debug window or file, which can be arbitrarily ignored, asserting the execution of the interrupt program. 2, the tracking statement in the MFC In the MFC, you can use Trace and AFXOutputDebugstring macros, COBject :: Dump virtual functions and AFXDUMPSTACK functions. The Trace Macro is implemented by AFXDUMP, and AFXDUMP is implemented by AFXOUTPUTDEBUGSTRING. AfxoutPutDebugstring Macro and AFXDUMPSTACK functions can be compiled in all versions, others can only be compiled in debug versions. (1) Trace macro has the following form: _Trace (ReportType, Format); _Trace0 (ReportType, Format, Arg1); _Trace1 (ReportType, Format, Arg1, Arg2); _Trace2 (ReportType, Format, Arg1, Arg2, Arg3); _trace3 (ReportType, Format, Arg1, Arg2, Arg3, Arg4); In the MFC, it is recommended to use Tracen Macros. When using Trace macro, it is necessary to use the _T macro to format parameters to properly resolve Unicode corrections, while Tracen does not need. One disadvantage in the MFC Trace macro is that the AFXTRACE function uses a 512-character fixed size buffer, which makes it useless when tracking the long string. (2) COBJECT :: Dump COBJECT class There is a dump (DUMP) virtual function, all of which inherited COBJECT classes can output their values ​​by overloading this function. 3, Visual C Message PRAGMA Message PRAGMA is actually a trace statement that is compiled, and you can use it to warn the potential editing (Build) issues found during the pre-processing. Typical examples: #IF (WinVer> = 0x0500) #pragma Message ("NOTE: WINVER HAS BEEN Defined As 0x0500 or Greater.") #ENDIF message PRAGMA is very useful, especially in complex. However, if you want to detect a specific problem, not a potential problem, use #error pretreatment instead of interrupting compiles more directly. Whenever you have errors in your program and you want more information, you should check the tracking message. Since the buffer of the VC output window is limited, if the speed generated by the tracking message data exceeds the speed of the output window processing, the message will be filled with the buffer, resulting in data loss. A simple way to avoid this problem is to call the Sleep API function when the code segment of the output of a large amount of data is output. Third, abnormal 1, basic concept error is a condition, under this condition, if additional processing is not performed, the thread does not perform it normally. An exception is used to handle errors. One obvious advantage of using an abnormality is that they can make the program code and the error handling code by issuing an error signal, and will not let the program ignore the error, and you don't have to keep check the return value of the function, so they simplify the program code . Another benefit is that they don't need a strict programming style. Abnormal basic characteristics:. Exceptions are based on each process and processed. Abnormal cannot be ignored by the thread, must be processed.

Unprocessed anomalies will end the process, not just end threads. Abnormally comes to release all stack objects when the stack is released, avoiding the vulnerability of resources. Abnormal processing requires a lot of additional operations, making it unsuitable for frequently running code. Can throw any type of abnormal object, except for integers. If it is correct, the exception handling has the following characteristics:. Exception is not a normal operation result, it is special case. The exception is used in the case where the return value is invalid. Violent is reliable and cannot be ignored. Abnormally simplifies the error handling, simplifies the program code, making the error handling more convenient. By default by Visual C , the exception is handled in the debug version, and the release is not processed in the release version. Since the exception is also an error, the Windows exception code uses a bit mapping mode as the Windows error code, which is a 32-bit value, which is defined by Microsoft, and the maximum four digits of any abnormal code are always 1100 (binary), ie 16 The 0xc in the encyclopedia. 2, Windows Structure Exceptions and C Abnormal Windows Structure Exceptions as hardware abnormalities (such as access illegal or zero-separated) or operating system exceptions are thrown, C exception can only be thrown by the throw statement. Windows structural exception handling cannot handle the resolution of the object, so you should use C exceptions in the C program. However, C abnormal cannot handle hardware and operating system exceptions, and your program needs to convert structural abnormalities to C exceptions. C exceptions do not throw from your program code but throw from the C runtime, so you need to call the stack window to return your code. In order to properly handle hardware and operating system exceptions, you can create your own anomaly class and use the _SET_SE_TRANSLATOR function to install a structure exception to C exceptions, but do not capture the structural exceptions that cannot be recovered. 3. Exceptions in the MFC In MFC, all exception objects are born in the CEXCEPTION base class (which is very convenient to use, and ReportError member functions). Most MFC abnormalities are dynamically allocated, and when they are captured, they must be deleted, and the MFC exceptions that are not captured are captured and deleted in the AFXCallWndProc function. 4. Expeeding When the C exception is thrown, the function call chain will search backttrocked to the processor that can handle this exception. If you didn't find it, the process ended. If found, the call stack will be released, all automatic (local) variables will also be released, and the stack will be organized as the context-related device of the exception processor. Therefore, exception overhead is an automatic variable table for an exception processor directory and an active auto variable (it requires additional code, memory, and whether it is thrown, it will run), and have to add a search and automatic variable of the function call chain. The adjustment of the stack (it only needs to be performed when throwing an exception). 5. Exception Policy (1) Time to throw an exception should be a function to find an error. If there is no special operation, the error can prevent the program from running normally, and this operation is not completed, or When the function is impossible to have a return value. Use exception handling easier, more reliable, more efficient, can create a more robust code. However, it should only use an abnormal handling in an accident.

If you think a pointer should be null, this value is checked directly in this condition without using an exception. (2) When to capture this problem, there may be some possible standards:. When the function knows how to handle this exception. When this function can reasonably handle this exception and advanced functions do not know how to handle it. When throwing an exception may cause the process to crash. When a function can continue to execute its task. When you need to organize allocation resources. A disadvantage of exception handling is that it may lead to the leakage of resources. Therefore, preventing resource leaks should be part of the maintenance process is safe. The stack is released automatically, and the local variable is automatically sorted, but does not include dynamically allocated variables. You can use a smart (SMART) pointer to protect your code without resource leakage without abnormalities. (3) How to capture. Non-MFC C exceptions should be captured by reference. Using reference capture exceptions do not need to delete an exception object (because the exceptions that use reference captures will be transmitted in the stack), and it retains polymorphism (so you captured the exception object is the exception object you thrown). . MFC abnormality should be captured by a pointer. Use pointer to capture exceptions require you to delete objects. Because they are usually allocated from the heap, when you process anomalies, you need to call the DELETE member function to delete. You can't use the omission capture processor to capture the MFC exception, which will cause a memory leak. You must use the DELETE member function to delete the MFC exception without delete because some MFC exceptions are created for static objects. Throw an exception during the release of the stack causes the process to terminate the process. The release stack involves calling the destructor, an exception can prevent calling the Delete operator, which will have resource leaks, so the exception is preferably not thrown from the destructive function. If you want to throw an abnormality in the destructive function, you must handle it to avoid resource leakage. 6. Abnormal and defensive programming continue to execute procedures during exceptions, which is important than performing a normal shutdown action. If possible, you should focus on continuing programs and close the program normally in a must-have. Maybe the most fundamental normal shutdown is a process that can restart your own when you crash, which is a technology used by the Windows Explorer. If a C exception associated with an error is expected, if it occurs in the code of the non-critical, if it does not occur in the result of the program startup or end or an unrecoverable structure, this program can be Restore it from it. Once your program can recover from an error related to the error, you should check the status of the program and its documentation. If the program and document have been destroyed, the process should also be terminated. Otherwise, the program needs to notify the client to determine the process of action. If the client agrees to execute, the program should recover errors and proceed. Fourth, the return value is not in the case, so it is not used in the case of using a Windows API programming or with COM programming. When an exception is not suitable, use the return value is a good way. The basic feature of the return value: The return value can indicate the normal and abnormal function running, but the thread will continue to run. The return value is easily ignored. The return value is an integer in a typical case, typically maps that conforming to a predefined value. The return value can transmit and receive efficiently. Therefore, the return value is best suited for the following scenario: for non-erroneous status information. For most cases, it is possible to ignore and no errors. For more prone to errors in the cycle. The error used in the intermediate language module, such as a COM component. Using the Visual C debugger debugging 1, the debug version and the release version sometimes program can run in the debug version but cannot run on the release version, and it is possible. Generally speaking, a release version means some types of optimization, and a debug version is not optimized.

Let's take a look at their differences: 1. Specially target the compilation option (1) / MDD, / MLD, or / MTD debug version of the debug version, which uses the debug stack, the purpose of the debug stack is to discover Memory damage and memory leaks, and report the source code from the user. Features:. The debug version of the runtime library is tracked for memory allocation, allowing users to check the memory leakage. Write the 0xcd byte mode in the just allocated memory, populate the originally assigned memory with 0xCD, helps discover errors that the data is not initialized. . In the released memory write 0xDD byte mode, helps discover the memory that has been released. The four-byte protection data is allocated on both sides of the buffer, and is initialized with 0xFD byte mode to check the overflow and underflow of write memory. The source code file name and line number are recorded in each memory allocation, which helps the user to position memory allocation in the source code. (2) / OD This option is used to turn off the optimized switch. Since the code that is not optimized directly corresponds to the source code, it is easier to read more than optimized code. Code compilation and links that are not optimized will be faster, there will be a shorter debug cycle. Due to optimization, the release version is not necessarily running more than the debug version, and the optimization code requires the compiler to do some hypothesis, remove redundancy, but sometimes this assumption is wrong, and the redundancy is also possible to hide errors. If the release version of the frame pointer (EBP register) omission (FPO) hides the error of the function prototype; in the synchronous exception mode (only by the throw statement, the compiler is default, the / gx compile option settings), exception The handler may be optimized, preventing the C exception processing code in the program, safely capturing the structure exception, in which case you must use asynchronous exception mode (taking any instructions, an exception mechanism, by / eHA Compile option settings ). (3) / d "_debug" opens the condition to compile the debug code switch. Only this symbol is defined, the debug code will be compiled, the MFC uses the _debug symbol to determine which version of the MFC class library is connected. In the debug version, inline defaults are turned off. (4) / zi Creates the program database of Edit and Continue. This option opens / gf compile options, / GF compilation options will eliminate repeat strings and put strings in read-only memory. Editing Continuous Function The special information stored in the PDB file is obtained to make the code modification is valid for the debugger. If the information corresponding to the modified file is not in the PDB file, the editing continuation function cannot be performed, and the following prompt information will appear in any modification of the code during the debugging process "One or more Files Are Out of Date or Do Not Exist." . (5) / GZ is used in debugging versions to find errors found in the release version. Its role is as follows:. Initialize the automatic (local) variable with 0xCC mode. Check the stack pointer when modifying a function by a function pointer, confirming that there is a call rule does not match. In the final inspection stack pointer is changed. (6) / GM open minimizes the re-link switch to reduce the link time. 2, specifically for publishing options (1) / MD, / ml, or / MT using the release version of the runtime library.

(2) / O1 or / O2 Open Optimization Switches, making the smallest process will be the fastest, the optimizer may also discover potential errors in the code, and these errors may be built by the debug version. (3) / D "NDebug" Close condition compiles debug code switch. (4) / GF eliminates repeated strings and puts them in read-only memory to avoid being modified by incorrectly. (5) / zi Creates a program database containing debug symbols. If an error only occurs in the release, unless you are a compilation master, you need to debug symbols to prompt you what is wrong to the program, and debug symbols are saved in the program database file (PDB). Visual C AppWizard is not created for a debug symbol for the publishing version by default. To create a debug symbol, open the engineering setup dialog, select the win32 release, select the common class in the C / C tag, in debug information, if it is a release version Select Program Database, if it is a debug version Select Program Database for Edit and Continue ( Editing Continue options are incompatible with optimized links, not suitable for publishing. Select the Debug class in the Link tag, then select Debug INFO and Microsoft Format options, it is best not to select the Separate Types option, so all debug information will be merged into a separate PDB file. For published versions, select the LINK tab, the final plus "/ opt: ref" in the Project Options dialog, this option makes the function and data that are not referenced, and the data does not appear in the executable, avoiding the unnecessary increase of the file. . Do not use this option for the debug version, it will turn off the incremental link (INCREMENTAL LINKING). Second, the "Settings" menu of the Visual C editor When you open or create a Workspace containing at least one project, the "settings ..." command in the Project menu of Visual C will become valid, select it or press the hotkey Alt. After F7, the engineering setup dialog can be called, which will affect the establishment and debugging process of the entire project, so it is important. In this dialog, the drop-down list box above the left is used to select an engineering configuration, including Win32 Debug, Win32 Release, and All Configurations (together with the first two configurations), some options have different engineering configurations. The default value. The tree view on the left gives all the files and classification of the current project. Let's take a look at the four main tabs related to the project (a total of ten tabs): 1, the General tab is relatively simple, from top down The first option is used to change the way using the MFC class library: the way in the DLL or static connection. We can switch between two ways. The second option is used to specify the memory of the intermediate file and output file generated during the compiled connection. For debug versions, the default directory is the "debug" subdirectory below. The third option is used to specify whether each engineering configuration has its own document dependencies (main point files), because the most engineering debug version and publish version have the same file dependencies, so there is usually no need to change This option is.

2, the Debug tab The Debug tab is some options related to debugging. Since the options are more, they are divided into several classes, we can select different categories from category, the tab will switch to display the appropriate options . In the General category, you can specify the executable file name to debug. The other three options can specify the working directory for debugging, start debugging command line parameters sent by the program, and the path to executable files during remote debugging. 3, the C / C tab C / C tab controls the Visual C compiler, where the options are more. There is a Project Options edit box below, and the various command switches listed will be transferred to the Visual C compiler when starting compiling. These command switches will change with other options. In the General category, WARNING LEVEL is used to specify the level of the compiler to display the warning. If WARNINGS AS ERRORS is selected, then each warning that is displayed will cause an error, so that the connector cannot be activated after compiling. . Optimizations is used to set up code optimization. Optimization is mainly two types of running speed and reduce program volume, but sometimes these two goals are contradictory. In addition, in a very small number of cases, the program can operate normally, and the program will have some inexplicable issues after the optimization measures are opened. In fact, this is mostly a potential error in the program, and the optimization measures are often only temporarily solved. DEBUG INFO is used to specify the type of debug information generated by the compiler. In order to use Visual C ie, that is, you must select the debug information of the "Program Database for Edit and Continue" type. Preprocessor definitions is some pre-defined macro names. The options in the C Language category involve some advanced features of the C language, including representations, abnormality processing, runtime type information, generally do not have to change them. The options in the Code Generation category involve how to generate target code, in general, keep the default value. In the Customize category, the meaning of the top six options is: whether to use Microsoft to the C extension; whether the function level is allowed; whether the duplicate string is eliminated; whether the minimized reconstruction is allowed; Increment compilation; whether the compiler is allowed to output its own version information to the Output window when the compiler is started. In the Listing Files category, we can specify the compiler to generate a browsing information and list file (Listing file), the former can generate a browsing information file by the browsing information maintenance tool Bscmake, the latter contains the C / C source file after compiling the compilation instruction. The Optimizations category allows us to make more submissive control over optimization, select which item is optimized, in Inline Function Expansion we can specify how the inline function is extended. The PrecompileD Headers category is about some options for the pre-translated header file, and no change is used in general. The Preprocessor category is about some options for pre-processing. 4, the LINK tab The LINK tab controls the Visual C connector.

In the General category, you can specify the file name of the output, and some additional library files or target files that need to be used during the connection, the meaning of the five options is: generate debugging information; ignore all default library files; Allows increment connection (this way can speed up the speed of the connection); generate a MAP file; allowing performance analysis. Selected User Program Database in Customize Allows the User Database. In the Debug category, we can specify the classes of the debugging information, or the Coff format, or both, or both, the connector will be subsequently put on the PDB file in the PDB file, which is connected to the PDB file in the PDB file. Some, but the speed of debugging will be slow. Input categories are some options related to the input library file, we can specify or do not use certain library files or target files here. In the Output category, some options related to the final output executable, generally do not change. Third, the Visual C Debug Tool 1, Debug Window (1) Observation Window (Watch) When you monitor variables and expressions can be monitored using the observation window. (2) Quick Watch feature and observation window are similar. (3) Variables Variable Window has three tags: Auto tags show the variables used by the current statement and the previous statement, the local variable of the current function, the THIS tab shows the object executed by the THIS pointer. (4) Register window (register) can monitor registers, flag values, and floating point stack (5) memory window (Memory) to display virtual memory from a specific address. The AddResS box allows you to specify which virtual memory address starts to display. (6) Call Stack window (Call Stack) can display a series of function calls that causing the current source code statement, the current function at the top of the stack. (7) Disassembly window (disassembly) to view assembly instructions generated by the compiler. 2, debug symbol program database file (.pdb) contains debugging information and program information required for the Visual C debugger. The debugging information contains the names and types of variables, function prototypes, source code line numbers, classes, and structural layouts, FPO debugging information (reconstructing stack frames), and information needed to increment links. For programs set up the Program Database for Edit and Continue option, the PDB also contains the information you need to perform editing proceeds. 3, using breakpoint breakpoints is a mechanism to run you to the debugger to describe the environment and set the debugger to set a mechanism. If there is no breakpoint, only one step in the program uses the debugger. In Visual C , you can set three types of breakpoints: code positioning breakpoint, data breakpoint, and message breakpoint. 4. Improve the error error of the debugger is trying to check the compile time instead of the runtime check. 1. Use the highest compilation warning level / w4 icon if (x = 2) such a statement, the default warning level does not display any information, but it will appear when it is changed to the highest warning level / w4 "WANING C4706: Assignment With Conditional Expression warning. / W4 gives some warnings that some / W3 can't give. 2. Use the / gz compile option / GZ option in the debug version to find out the errors that are discovered in the release, including automatic (local) variables that are not initialized, stack errors, incorrect function prototypes.

3. Use the #pragma warning compiler to indicate you can use the #pragma warning compiler to disable the entire program, a specific header file, a specific code file, or a specific warning of a specific row code, which looks #pragma. where is it. 4. Use no warning compile / wx this compilation option to treat all warnings as an error, only after the false warning is eliminated. Sometimes compiling warnings may be reasonable, and the core of processing compilation warning is to discover errors, rather than suppressing warnings themselves. This law is very helpful for big procedures development groups. The ultimate goal is to eliminate errors, not to eliminate warnings. V. Memory Space and Distribution 1, Memory Allocation Error Dynamic Memory Allocation Errors There are two basic types: memory error and memory leakage. (1) Memory error When a pointer or the memory cell pointing to the pointer becomes an invalid unit, or when the data structure allocated in memory is destroyed, the memory error is caused. The pointer is not initialized, the pointer is initialized to an invalid address, the pointer is unclearly modified, and the pointer is used after the memory area associated with the pointer (this pointer is called a dangling "pointer), these It will make the pointer into an invalid pointer. When written by an error pointer or a virtual resuscitation, or converting the pointer to a non-match data structure, or written the data, the memory itself is destroyed. Delete the uninitial pointer, delete the non-heap pointer, delete the same pointer multiple times, or covers the internal data structure of a pointer, will cause memory allocation system errors. (2) The memory leak memory leak is generated when the memory being dynamically allocated is not released. There are many situations that cause memory leaks, such as release memory in all execution paths of the program, not release all memory in the destructor. The longer running before the crash is collapsed, the larger the cause of the crash and the relationship between memory leakage. Windows reclaims the leak memory at the end of the program, so memory leak is a temporary issue. But why must I eliminate memory leaks? First, memory leaks often lead to leakage of system resources. Dynamic allocation of memory often represents a storage area, but also represents certain types of system resources, such as files, windows, device contexts, GDI objects, and more. Second, high quality procedures and specific server programs must be able to run unlimited. Finally, memory leaks are often signs of other programs or bad programming habits. Causes leading to internal ginseng leaks: forget to release memory; constructor failed; there is a destructive function for memory leakage; there is an exception handler for memory leaks; multiple returns; use the error form. 2. About the initialization of memory In the debug version, the memory that is not initialized in the stack is populated by the 0xcd byte mode, and the memory released by the pile is filled with the 0xDD byte mode. The memory in the stack is initialized by the 0xcc byte mode. In the debug version and the release version, the global memory that is not initialized is initialized to 0. 3. Memory Virtual Address Space Windows uses a set of fixed ranges to segment the 4GB virtual address space of the process, so it is sometimes judged by the return value of the pointer to determine if the pointer is valid.

转载请注明原文地址:https://www.9cbs.com/read-116432.html

New Post(0)