C ++ programming specification 7 exception and error handling

Source: Internet
Author: User

7. Handling exceptions and errors

7.1 exceptions

Exceptions are a powerful feature of the C ++ language. Before you use them correctly, you need to understand the context of the Exception Code.

Principle 7.1 reduce unnecessary exceptions

Note: exceptions have higher requirements on coding skills and are prone to errors during use. First, consider using them as little as possible or avoid exceptions from the security perspective.

Compared with the returned error, the exception has the following advantages:
Exceptions can be captured in a centralized manner. Error Detection is separated from algorithm processing, and the algorithm logic is clearer. Errors returned at each return point

The Code logic is scattered for detection and error handling.

The exception is more restrictive. You cannot ignore the thrown exception. Otherwise, the program will be terminated by default, and the returned error may be ignored.

Exceptions also have obvious disadvantages:

You must check whether all call points may throw an exception. After the throw, you must correctly handle the status and resource variables. Otherwise

Incorrect object status or resource leakage. For example, if F () calls g () and H () in turn, H throws an exception captured by F,

G should be careful to avoid resource leakage.

All exceptions that may be thrown must be clearly identified and captured in appropriate places. If omitted, the program will usually be terminated.

When exceptions are used, it is difficult to evaluate the control flow of the program, and it is difficult to debug the code.

The target file becomes larger, the Compilation Time is prolonged, and the performance is degraded.

If you do not fully understand the exception, an exception may be thrown at an inappropriate time or recovered from the exception in an insecure place.

Applicable to exception scenarios:

An error that does not occur cannot be ignored and must be processed. For example, the memory allocation fails.

Upper-layer applications decide how to handle "impossible" failures in the underlying nested functions.

The error code is difficult to return through function return values or parameters, such as stream.

Many third-party C ++ libraries have usage exceptions and must be used in conjunction with third-party C ++ libraries at system boundaries to facilitate integration with these libraries.

It is convenient to use exceptions in the testing framework.

Rule 7.1 constructor and destructor cannot throw an exception

Note: If the constructor and destructor fail to be executed, undo and roll back safely. Therefore, these functions cannot throw an exception.

To reduce complexity, we recommend that you implement the simplest logic in such functions.

Rule 7.2 is thrown by passing values and captured by referencing

Note: If a pointer is thrown when an exception is thrown, it is a problem to release the pointer. If a value is uploaded during capturing, a copy will exist, and the copy can

Failed (for example, the exception is caused by memory depletion), and the object of the derived class cannot be copied, because during the copy, the object of the derived class

Will be sliced into a base class object.

Rule 7.3 ensures that thrown exceptions are captured.

Note: exceptions are not caught. The default behavior of the system is to terminate the program running, so ensure that all exceptions generated by the program can be caught.

Rule 7.4 ensures that resources do not leak when an exception occurs

Note: When an exception occurs, the current code execution sequence is interrupted. Check whether the allocated memory, file, Kernel Handle, and other resources are correct.

Release to avoid resource leakage, especially whether the resources are correctly released at each possible return point.

Example: Memory leakage occurs in the following code:

Int portaltransformer: transrls
{
Rls_service * service = NULL;
New (Service, rls_service );
Parser-> adoptdocument (); // an exception is thrown when a failure occurs.
//....
Delete service;
Service = NULL;
Return 0;
}
The exception that occurs when adoptdocument is called is not caught in the transrls function. Instead, the exception derivation is captured in the parent function.

Class. If an exception occurs, the memory allocated by new (Service, rls_service) is leaked.

Solution: capture the exception of adoptdocument in the transrls function. If an exception occurs, delete the pointer service.

Rule 7.5 external interfaces of independent compiling modules or subsystems are prohibited from throwing exceptions

Note: There is no universal binary standard for exception handling, so cross-module Exception throwing is not allowed.

7.2 error handling policy

Principle 7.2 establish a reasonable error handling policy

Note: The errors mentioned here refer to runtime errors, rather than internal programming and design errors. Module Internal programming and design error

It should be marked by assertion.

Early Design of error handling policies, including: identification, severity, error check, error handling, error transfer, Error Reporting

Solution.

Error Identification: for each object (function, class, module), record the internal and external non-variant, pre-condition, post-condition of the object

And the error security guarantee it supports.

Severity: indicates the severity of each error.

Error Check: For each error, it indicates which code is responsible for checking it.

Error Handling: indicates the code responsible for processing each error.

Error Report: indicates the appropriate reporting method for each error.

Error transfer: for each module, indicate the programming mechanism used to pass errors, such as C ++ exceptions, CORBA exceptions, and returned values.

The error handling policy should be changed only at the module boundary. If the policies used inside and outside the module are different, all module entry functions must be direct

It is responsible for the conversion from internal to external policies. For example, in a module that uses C ++ exceptions internally but provides the API boundaries of C language, all

C language APIs must use catch (…) to catch all exceptions and convert them into error codes.

Principle 7.3 handle errors or conversion errors closest to errors

Note: When a function detects an error that cannot be solved by itself and causes the function to fail to be executed, an error should be reported.

If there is no processing context, the error should be propagated up.

When Rule 7.6 errors occur, at least ensure that they comply with the basic guarantee; at least ensure that transactions are processed; and for atomic operations

No error guarantee

Note: The basic guarantee means that the access object status is correct. The strong guarantee is an enhancement to the basic guarantee, not only must the status be correct,

In addition, when a failure occurs, the status should be rolled back to the status before the operation, either it is successful or nothing is done. If there is no error, the failure cannot be ensured.

Strictly Following this principle in coding will greatly improve program robustness.

Sample Code that complies with the basic guarantee: the following code resolves the input stream to the object, and throws an exception to the stream to report an error.

Void cmessage: parse (istream * input)
{
Try
{
M_uimessagelen = input. readinteger (); // an exception is thrown when a failure occurs.
If (0 = m_uimessagelen | m_uimessagelen> max_message_len)
{
Throw invalid_argument ("Invalid Message Len in cmessage: parse ");
}
M_pmessage = new char [m_uimessagelen]; // an exception is thrown when a failure occurs.
Input. Read (m_pmessage, m_uimessagelen); // an exception is thrown when a failure occurs.
//.....
}
Catch (const exception & exp ){
Resetcontent (); // set all fields of the object to invalid
Throw exp;
}
Return;
}
In the previous example, make sure that the values of the object fields are either valid or invalid, and some valid values are not invalid. Otherwise, the exception must be handled.

The status of objects that are often thrown, which makes the caller easy to miss. Therefore, the interface should at least comply with the basic guarantee.

This function can be transformed to a strongly qualified guarantee, as shown below:

Void cmessage: parse (istream * input)
{
Cmessage temp;
Try
{
Temp. m_uimessagelen = input. readinteger (); // an exception is thrown when a failure occurs.
If (0 = temp. m_uimessagelen | temp. m_uimessagelen> max_message_len)

{
Throw invalid_argument ("invalid messagelen in cmessage: parse ");
}
Temp. m_pmessage = new char [temp. m_uimessagelen]; // an exception is thrown when a failure occurs.
Input. Read (temp. m_pmessage, temp. m_uimessagelen); // throw an exception when a failure occurs.
//.....
}
Catch (const exception & exp ){
Temp. resetcontent (); // set all fields of the object to invalid
Throw exp;
}
Swap (temp); // run swap
Return;
}
After a failure, the status of the object is not affected. After successful, the executed swap must meet the non-error guarantee. Otherwise, this function cannot be supported.

Strong guarantee.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.