I am finding that using assert(...)
makes my code shorter and easier to read, as opposed to lengthy if..else..
blocks. However, are there good technical reasons not to use assert(...)
in shipping code, when it does the same thing as testing a return
value while using less code?
相关问题
- Multiple sockets for clients to connect to
- What is the best way to do a search in a large fil
- glDrawElements only draws half a quad
- Index of single bit in long integer (in C) [duplic
- Equivalent of std::pair in C
IMO none of the answers here says the most important part: Assert states programmers assumptions.
assert(x)
says something like "x is always true at this point, you can check that if you want". If the user ever sees assertion error, it means you did something wrong.What you probably need is a function which would do almost the same thing as assert, but both in release and debug modes. Using
check(x)
would mean "Check that x is true. If it isn't, tell the user and quit"I don't share the point of those who say it's valid. Once I've got screwed by the fact that Qt's asserts were defined like as follows:
and I used to write something like
When I've complied it in release mode, I was quite puzzled by
a
never initialized.assert()
is designed for things that are never supposed to be false in sane circumstances.if
-else
is designed for things that may sometimes be false in sane circumstances, because theelse
portion is designed for handle such situations gracefully.In short,
if
statements are designed to avoid crashes;assert()
is designed to cause them.If it's a programming error (possibly by the caller), use an
assert
.If it's not a programming error, then use
if
/else
and handle the situation appropriately.Having read this article I will share my beliefs about
assert
:Yes it's fine to use
assert
when something absolutely should meet the condition you are asserting.Many languages allow you to raise custom errors when asserting, C not having "Exceptions" may produce errors that are a little harder to diagnose without directly looking at the source in question.
I think using
assert
for runtime errors is poor form, particularly because it defies convention:assert
typically is compiled out of non-debug builds. Now, you might choose to compile all your builds with the expectation thatassert
is always enabled, but anyone who inherits your code later might not understand that. It'll be even worse if you write code where yourassert
s have side-effects (such asassert((fp = fopen(filename, "r")) != NULL)
).Similarly,
assert
is intended to be used for logical errors, not runtime errors. When you start usingassert
to check runtime errors, you start misrepresenting how your code is supposed to behave to anyone who tries to read it. Maintainers will not be able to distinguish easily between logical errors and potential runtime errors, and the distinction is useful when reasoning about code behavior.And do you really want your program to terminate abruptly and dump core if a user accidentally leaves some input field blank? That's incredibly user-hostile.
If you feel that using
assert
is less code, then you could try writing your own, separate macro. That would avoid changing the expected semantics ofassert
and the hostility. For example, something like: