Assert() - what is it good for ?

怎甘沉沦 提交于 2019-12-06 06:45:18

问题


I don't understand the purpose of assert() .

My lecturer says that the purpose of assert is to find bugs .

For example :

double divide(int a , int b ) 
{
  assert (0 != b);
  return a/b;
}

Does the above assert justified ? I think that the answer is yes , because if my program doesn't supposed to work with 0 (the number zero) , but somehow a zero does find its way into the b variable , then something is wrong with the code .

Am I correct ?

Can you show me some examples for a justified assert() ?

Regards


回答1:


assert is used to validate things that should always be true if the program is correct. Whether assert is justified in your example depends on the specification of divide: if b != 0 is a precondition, then the assert is usually the preferred way of verifying it: if someone calls the function without fulfilling the preconditions, it is a programming error, and you should terminate the program with extreme prejudice, doing as little additional work as possible. (Usually. There are applications where this is not the case, and where it is better to throw an exception, and stumble along, hoping for the best.) If, however, the specification of divide defines somw behavior when b == 0 (e.g. return +/-Inf), then you should implement this instead of using assert.

Also, it's possible to turn the assert off, if it turns out that it takes too much runtime. Generally, however, this should only be done in critical sections of code, and only if the profiler shows that you really need it.

FWIW: not related to your question, but the code you've posted will return 0.0 for divide( 1, 3 ). Somehow, I don't think that this is what you wanted.




回答2:


Another aspect of assertions:
They are also a kind of documentation.

Instead of comments like

// ptr is never NULL
// vec has now n elements

better write

assert(ptr!=0);
assert(vec.size()==n);

Comments may become outdated over time and will cause confusion. But assertions are verified all the time.
Comments can be ignored. Assertions cannot.




回答3:


You're pretty much spot-on in your assesment of assert, except for the fact you typically use assert during a debug-phase ... This is because you don't want an assert to trigger during production code ... throwing exceptions (and properly handling them) is the proper method for run-time error-management in production level code.

In general though, assert is used for testing an assumption. If an assumed condition is not met in the code during the debugging phase, especially when you are getting values that are out-of-bound for the desired input, you want your program to bail out at the point that the error is encountered so you can fix it. For instance, suppose you were calling a function that returned a pointer, and that function should never return a NULL pointer value. In other words returning a NULL value is not just some indicator of an error-condition, but it means that the assumption of how you imagine your code works is wrong. That is a good place to use assert ... you assume your program will work one way, and if it doesn't then you don't want that error propagating to cause some crazy hard-to-find bug somewhere else ... you want to nix it right when it occurs.

Finally, you can combine built in macros with assert such as __LINE__ and __FILE__ that will give you the file and line number in the code where the assert took place to help you quickly identify the problem area.




回答4:


The purpose of an assert is to signal out unexpected behavior during debugging (as it's only available in a debug build). Your example is a justified case of assert. The next line would probably crash, but with the assert there you have the option to break execution right before the line is hit, and do some debugging.

This is usually done in parallel with exceptions - you assert to signal that something is wrong, and throw an exception to treat the case gracefully (even exiting the program):

double divide(int a , int b ) 
{
  assert (0 != b);
  if ( b )
     return a/b;
  throw division_by_0_exception();
}

There are cases where you want to continue execution, but still want to signal that something went wrong.




回答5:


Assert is used to test assumptions about your code in a debug environment. Asserts generally have no effect on your final build.

Whether or not it is a valid test is another matter entirely. We can't answer that without intimate knowledge of your application.

Asserts should never fail. If you see any possibility that the assertion could fail, then you need an if statement instead to handle those cases where the condition is not true. Assertions are only for conditions that you believe will never fail.




回答6:


Asserts are used to check invariants during code execution, those are the conditions that are assumed by programmer to always stay the same, if they differ from assumptions then there is a bug in the code.

Asserts can be also used for checking preconditions and postconditions, the first is checked before some code block and verifies if provided data/state is correct, the second one checks whether the outcome of some calculations are correct. This helps to narrow where problems/bugs might be located:

assert( /*preconditions*/ );
/*here some algorithm - and maybe more asserts checking invariants*/
assert( /*postconditions*/ );

Some examples of justified asserts:

  1. Checking function return value, for example if you call some external API function and you know that it returns some error value only in case of programming error:

WinAPI Thread32First function requires that provided LPTHREADENTRY32 structure has properly assigned dwSize field, in case of error it fails. This failure should be catched by assert.

  1. If function accepts pointer to some data, then add assert at the start of function to verify that it is non-null. This makes sense if this function cannot work on null pointer.

  2. If you have a lock on mutex with set timeout then if this timeout ends then you can use assert to indicate possible race condition / deadlock

... and many many more

Nice trick with asserts is to add some info inside, ex.:

assert(false && "Reason for this assert");

"Reason for this assert" will show up to you in a message box

You might also want to know that we also have static asserts that indicate errors during compilation.



来源:https://stackoverflow.com/questions/12161998/assert-what-is-it-good-for

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!