Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is another error handling strategy of C++?

2025-02-27 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

What is another error handling strategy of C++? for this question, this article introduces the corresponding analysis and answer in detail, hoping to help more partners who want to solve this problem to find a more simple and feasible way.

This short article discusses a topic that most programmers are interested in: error handling. Error handling is a "dark side" of programming. It is not only the key point of the "real world" of the application, but also a complex business that you want to hide.

In my early career in C programming, I knew three ways to handle errors.

C language way: return error code

C-style error handling is the easiest, but not *.

C-style error handling depends on "returning an error code when the program encounters an error". Here is a simple example:

Int find_slash (const char * str) {int I = 0; while (str [I] & & str [I]! ='/') iTunes; if (str [I] = ='\ 0') return-1; / / Error code / / True value return i;} / /. . . If (find_slash (string) =-1) {/ / error handling}

What are the advantages of using this way?

You can handle the error code directly after calling the function (as you would in C), display an error message or terminate the program directly. Or simply restore the most recent state of the program and terminate the calculation.

When you can't find where the error handling is, you just need to look at the function call later, and the error handling is near there.

What's wrong with using this way?

Someone may tell you that this exception / error handling is mixed with "execution logic". When you read the code sequentially, just as the program executes, you see error handling and program execution. This is bad, and you may prefer read-only program execution logic or error handling logic.

And you are limited to using error codes, if you want to provide more information, you need to create some functions such as: errstr or provide global variables.

The way you use C++

As an enhancement of C #, C++ introduces a new way of error handling-exception. Exceptions interrupt normal code execution logic by throwing an error and can be caught elsewhere. Here is a simple example:

Int find_slash (const char * str) {int I = 0; while (str [I] & & str [I]! ='/') iTunes; if (str [I] = ='\ 0') throw AnException ("Error message"); / / True value return i;} / /. . . Try {find_slash (string);} catch (AnException& e) {/ / Handle exception}

What are the benefits of this?

Program logic is separated from error handling. On one side you can see how the function works, and on the other you can see what happens when the function fails. This is very difficult, and you can easily see the error handling and normal program logic.

In addition, you can now provide as much information as you need for your errors, because you can populate the custom exception objects with what you need.

The disadvantages of doing so

It becomes cumbersome to write detailed exception handling. You need an exception tree, but not too big so that you can choose to catch the exception you are interested in. At the same time, you need to provide an error code internally to know exactly what happened, and you need to retrieve some error messages, and so on. Writing exception classes is usually lengthy, which is the cost of embedding information into errors to handle more information flexibly.

The philosophy of error handling here is to postpone the error to where it needs to be handled as far as possible. when you don't know exactly where an error will occur during the execution of the program, you need to skip different files and functions to find it. this is usually difficult if you are in a deep call tree (which means when you draw a graph by calling a function An exception is thrown in the shape of a tree). You need to specify where to handle the exception and where it occurs when it is handled. Especially when your program is very large, and it was written a long time ago, and the design happens to be not good enough, it becomes more difficult. This is the case with most business projects.

So I think "abnormality is dangerous". Although it provides a good way to handle errors-limited to small projects, and the call diagram here is simple and easy to master.

Mode of error encapsulation

I call it a pattern here, so people don't have to be afraid to worry. Later, I will give it a better name, so please don't worry.

The main idea of error encapsulation is to create an encapsulation to contain error messages or error return values. We usually choose strings over others, because this is not easy to implement. We try our best to ensure that the grammar is readable, understandable, and easy to use. We do not deal with copy constructs or multi-parameter functions and return values, but here is just a simple example as simple as possible.

Let's start with the following example:

E find_slash (const char* str) {int I = 0; while (str [I] & & str [I]! ='/') return fail; if (str [I] = ='\ 0') return fail ("Error message"); / / True value return ret (I);} / /. . . Auto v = find_slash (string); if (! v) {/ / Handle exception}

At first glance, it looks a bit like C, but it's not. To illustrate this, take a look at the following examples of function calls:

E find_slash (const char*); E do_some_arithmetic (int); E format (int); E display (std::string); auto v = ret (string) .bind (find_slash) .bind (do_some_arithmetic) .bind (format) .bind (display); if (! v) {/ / Handle error}

All right, what's going on here? Bind is a member function to bind your function call, try to apply it. If the error box contains a value, it is applied to the function call and continues to return an error box (the compiler does not allow you to return a function without error boxing).

So, we chained find_slashe,do_some_arithmetic, format and display. All of them do not handle error boxing. Because of the function bind, we return the result of the function EF (something_in) to the function EF (E) as a parameter.

What are the benefits here?

Once again, function logic (call chain) and error handling are separated. As with exceptions, we can simply read the function call chain to understand the code logic, regardless of where execution is interrupted. In fact, the function call chain can be broken on any call. But we can assume that no errors have occurred, and if our logic is correct, we can check it very quickly.

Of course, type inference will prevent you from continuing binding after calling display. So we haven't lost our type of ability.

Notice that we don't call these functions elsewhere, we assemble these methods together in *. Here is the key, you should write some small module functions (in addition, note: you should write template functions to make it work) to receive a value, and then calculate a new value or return a failure. At each step, you do not need to consider that an error may interrupt your control flow, and verify that you are in a valid state (exception security is based on querying each function call and indicating whether the function interrupts your control flow. Based on this, it is safer to do so.

Like exceptions, we can handle very detailed information, although here we write a partial template function, so it is easier to understand.

We can easily place the exception handling logic after the function call chain (unless the return value needs to be further linked). Now, we have a large execution flow, no interruption, use small functions to handle the flow, easy to locate. When you need to add a new error, you just need to find those functions, through the function call chain, you can directly locate the processing location and add as needed. Large projects become more linear and easier to read.

What are the shortcomings of this?

First of all, this is a new way of handling, and it is not compatible with the C++ way. This is not a standard method of handling, and you still need to use exceptions when you use stl.

For me, this is still a bit lengthy. You need to explicitly write fail (… The template derivation of) is a little weird, and it's even worse if you have a polymorphic error type, you have to write fail ("...").

It is also difficult to write when a function has multiple arguments, and in some other languages, applicable and abstract types can be used to solve this problem, but this is not provided in C++. I think it is more suitable to use bind2 (E, E, f) and bind3 (E, f). The variable template parameter function is more useful.

To get the value in the encapsulation error, we need to check that the value is a valid value, and then call a "to_value" method. We can't do this without checking. What we want is to "deconstruct" an object, which is not supported in C++, nor are these features that can be said, "Let's add it to the next standard."

So far, I don't know if the reader has a way to adapt it to the member function, if you have any ideas, please test it, and if you can, please let us know.

Implement atomic error handling

I implemented it, I defined the name of the dark magic-"atomization", you can think of "atomization" as a box of values and error contexts, for example, a box contains a value or nothing is an atomic group (here as an exercise, you can try to implement it).

Oddly enough, in a way, a queue is an atomic group that has a context value.

Let's start with the above E-template class implementation, which uses the decltype and auto-> decltype types in the Cellular template 11 standard, which allows automatic derivation of the type of expression, which is very useful.

The bind function here is a little weird, but it implements what I just mentioned.

This is the answer to the question about what is another error handling strategy of C++. I hope the above content can be of some help to you. If you still have a lot of doubts to be solved, you can follow the industry information channel for more related knowledge.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report