What is the strategy if approval fails

The statement is used to check whether the condition (precondition, postcondition, invariants) is fulfilled and help programmers find holes during the debug phase.

For example,

void f(int *p) { assert(p); p->do(); } 

My question is that we should assume that the condition cannot be fulfilled in the release mode and process the register accordingly?

 void f(int *p) { assert(p); if (p) { p->do(); } } 

In the end, a statement means that the condition being tested must NEVER be false. But if, if we do not verify this and fail, the program will fail. Sounds like a dilemma. How do you handle this?

+7
c ++ assertion
source share
8 answers

If approval fails, the program should crash .

An assertion error means that the programmer made a fundamental mistake in understanding how this is possible for the program flow. This is development assistance, not production assistance. In production, exceptions can be handled because they can “happen”, while assertions should “never” work.

If you are in a camp that says, “Oh, but what if the statements do not work in production? I need to catch them.” then you are missing the point. Ask yourself, then, why are you not just throwing an exception (or otherwise handling the error)?

Generally speaking, a statement is not just an abbreviation for “if the condition is not met, the exception is an exception” (well, sometimes it’s operational semantics, but it’s not denotational semantics). Rather, a denial of approval means that the application is in a state that the developer does not even consider possible . Do you really want the code to continue to run in this case? Clearly (I would say) No.

+20
source share

Protective programming is always better. You should always assume that, despite all your trials, your application will be sent with errors. Thus, it is in your best interest to add NULL checks in situations where you can avoid the sign of a NULL pointer and just move on.

However, there are situations where there is no easy way to avoid a failure, and in these cases, approval is your only way to detect a problem during the development cycle.

One important point - claims are also often used to detect serious integrity issues for your data. If you continue with these statements, you risk corrupting the data. In such cases, it may be better to crash rather than destroy your data. (Obviously, any kind of fault handler that at least creates a reasonable interface with error descriptions would be preferable).

+2
source share

Strictly speaking, the second code has redundancy.

 void f(int *p) { assert(p); if (p) // Beats the purpose of assertion { p->do(); } } 

Validation means an error has occurred. Something unexpected / unprocessed. In the above code,

1) You correctly handle the case when p is null. (without calling p-> do ()), which is supposedly correct / expected. However, then the statement is a false alarm.

2) On the other hand, if you do not call p-> do (), something goes wrong (perhaps in the code or in the output), then the statement is true, but there should be no sense in any case.

In the above code, the programmer makes extra efforts to handle cases that are in any case erroneous.

However, some people like to relate to statements because something went wrong, but let's see if we still get the right result. IMO, this is a bad strategy and creates confusion when fixing errors.

+1
source share

Assertions are debugging code, not working code. Do not use them to detect input errors.

0
source share

Statements are used to detect errors during testing. The theory is that you tested well enough to know that it will work after you release it.

If it is likely that a condition may arise in real life, do not rely on statements - use exceptions or some other error mechanism.

0
source share

Accessors are useful for debugging, as you mentioned. They should never turn them into production code (as compiled, it's ok to wrap it in #ifdefs, of course)

If you run into a problem where the fix is ​​not subject to control, and you need a check in your production code, I would do something like:

 void f(int *p) { if (!p) { do_error("FATAL, P is null."); } p->do(); } 

Where do_error is a function that logs an error and clears it.

0
source share

I say leave them in the assembly for assembly. There will be errors in any assembly. Having statements in your product means that you can more accurately identify a problem when you receive a problem report using à uwer.

Do not exert much effort in handling exceptions. Just make sure you can get the full exception, includingigg stacktrace. This applies, in particular, to the release of the assembly.

0
source share

As many people comment on posting statements in release mode:

What I'm working on, efficiency is very important (sometimes it takes from several tens of hours to several days to complete large data sets). Therefore, we have special macros that only validate in debugging code (run during QA, etc.). As an example, a statement inside a for loop is a certain overhead, and you can avoid it in the release code. In the end, if all is well, statements should not fail.

One example that asserts a release code is that the logic should not fall into a particular branch of code. In this case, assert (0) is fine [so any type of assert (0) can always be left in release code].

0
source share

All Articles