Is assert evil?
Solution 1
No, there's nothing wrong with assert
as long as you use it as intended.
That is, it's supposed to be for catching cases that "can't happen", during debugging, as opposed to normal error handling.
- Assert: A failure in the program's logic itself.
- Error Handling: An erroneous input or system state not due to a bug in the program.
Solution 2
No, neither goto
nor assert
are evil. But both can be misused.
Assert is for sanity checks. Things that should kill the program if they are not correct. Not for validation or as a replacement for error handling.
Solution 3
By that logic, breakpoints are evil too.
Asserts should be used as a debugging aid, and nothing else. "Evil" is when you try using them instead of error handling.
Asserts are there to help you, the programmer, detect and fix problems that must not exist and verify that your assumptions stay true.
They have nothing to do with error handling, but unfortunately, some programmers abuse them as such, and then declare them "evil".
Solution 4
I like to use assert a lot. I find it very useful when I am building applications for the first time (perhaps for a new domain). Instead of doing very fancy error checking (that I would consider premature optimization) I code fast and I add a lot of asserts. After I know more about how things work I do a rewrite and remove some of the asserts and change them for better error handling.
Because of asserts I spend a lot of less time coding/debugging programs.
I've also noticed that the asserts help me think of many things that could break my programs.
Solution 5
As an additional information, go provides a built-in function panic
. This can be used in place of assert
. E.g.
if x < 0 {
panic("x is less than 0");
}
panic
will print the stack trace, so in some way it has the purpose of assert
.
Related videos on Youtube
Frank
Updated on July 08, 2022Comments
-
Frank almost 2 years
The
Go
language creators write:Go doesn't provide assertions. They are undeniably convenient, but our experience has been that programmers use them as a crutch to avoid thinking about proper error handling and reporting. Proper error handling means that servers continue operation after non-fatal errors instead of crashing. Proper error reporting means that errors are direct and to the point, saving the programmer from interpreting a large crash trace. Precise errors are particularly important when the programmer seeing the errors is not familiar with the code.
What is your opinion about this?
-
allyourcode over 8 yearstangent: Go is an unusually opinionated language. This isn't necessarily a bad thing. However, it does mean you should take its opinions with a bigger grain of salt. It also means that if you disagree, you are going to be gnashing your teeth as you use the language. As evidence of how Go clings to its opinions despite reality, consider that you need to resort to the magic of reflection to determine if two collections are equal.
-
Igor Dubinskiy over 8 years@allyourcode If you're referring to
reflect.DeepEqual
, you certainly don't need it. It's convenient, but at the cost of performance (unit tests are a good use case). Otherwise, you can implement whatever equality check is appropriate for your "collection" without too much trouble. -
allyourcode over 8 yearsNo, that's not what I'm talking about. There is no such thing as slice1 == slice2 without reflection. All other languages have an equivalent to this super basic operation. The only reason Go does not is prejudice.
-
kbolino over 6 yearsYou can compare two slices without reflection using a
for
loop in Go (just like C). It would be really nice to have generic slice operations, although comparison gets complicated when pointers and structs are involved.
-
-
Peter Cordes over 14 yearsassert is good for declaring the pre-conditions at the top of a function, and if clearly written, acts as part of the documentation of the function.
-
Admin over 14 yearsIf you look at my answer. My use is to differentiate 'exceptions' (asserts) that i want to get rid of used for debugging vs exceptions that i keep. Why would i want to get rid of them? because without them working it would not be complete. Example is if i handle 3 cases and the 4th is todo. I can easily search assert to find them in code and know its incomplete rather then use an exception that might accidentally be caught (by another programmer) or hard to tell if i its an exception or a logic check that i should solve in code.
-
Evan Carroll over 14 yearsIn my eyes, this is a poor idea, on the same level as "sealed" classes and for just the same reason. You're assuming the exceptions you want to keep are acceptable for uses of your code you don't yet know of. All exceptions go through the same channels, and if the user doesn't want to catch them he can choose not to. If he does, he should have the ability too. Either way, you're just making assumptions or pushing off your practice with a concept like an assertion.
-
Admin over 14 yearsI decided example scenarios are best. Heres a simple one. int func(int i) { if(i>=0) { console.write("The number is positive {0}", i); } else { assert(false);//to lazy to do negatives ATM } return i*2; <-- How would i do this without asserts and is an exception really better? and remember, this code will be implemented before release.
-
Evan Carroll over 14 yearsSure exceptions are better, lets say I take user input and call
func()
with a negative number. Now, suddenly with your assertions you've pulled the carpet out from under me and not given me a chance to recover, rather than politely telling me what I'm requesting can't be done. There is nothing wrong with accusing the program of being misbehaved and issuing it a citation: the problem is you're blurring the act of enforcing a law, and sentencing the felon. -
Admin over 14 yearsThats the point, you SHOULDNT say what the user wants to do cant be done. The app should terminate with the error msg and whomever is debugging would remember its something that SHOULD BE DONE but isnt. You DONT want it to be handled. You want a termination and to be reminded you didnt handle that case. and its extremely easy to see what cases are left since all you need to do is a search for assert in code. Handling the error would be wrong since the code should be able to do it once ready for production. Allowing a programmer to catch it and do something else is wrong.
-
Admin over 14 yearsNOTE to others. The func in my example above should do
console.write("The number is negative {0}", i);
and not throw an exception. This is why assert is a DEBUG tool and not an error handling tool. Thats why no one should writedraw(){ Assert(image.exist())
because saying it isnt handle or the user did it wrong (exceptions) isnt the same as saying it will be handled but isnt yet. -
Evan Carroll over 14 yearsre
You DONT want it to be handled.
. You shouldn't code assuming you know the use-cases of your code. It doesn't matter what you want, if someone else wants to handle it they should be allowed to, it is their freedom to do what they wan't and you shouldn't impose yourself with code. You disagree, you want to be the controller of your codes application. That is fine, I just disagree that it is ever a good thing. Your examples say something of your argument, if you try to draw an image that doesn't exist, the whole program should die because it failed your assertion... right... -
Admin over 14 yearsNo you misunderstand. I am not saying you shouldnt be able to handle it the way you like. I am saying if the function should be able do something like load an image and it doesnt then an assert should be in place because your not done the code yet and if you accidentally load an image forgetting your not done it you'll notice it instead of running into exception code. This is why the draw code should never check if an image exist with an assert. An assert belongs in an empty loadimage function and an exception belongs in a draw function when no image has been loaded.
-
vmasule over 13 yearsThe difference is "exceptional" vs. "impossible". See here: stackoverflow.com/questions/1467568/…
-
João Portela over 13 years90% percent of statistics used in arguments are false.
-
Zippo over 12 yearsNot too bad :-) Exceptions or not, assertions or not, Go fans are still talking about how short are the codes.
-
David Stone about 12 years
new
never returnsnullptr
, it throws. -
Nir Friedman about 9 yearsGo does not have exceptions. The usual reason to use an assert rather than an exception is because you want it elided in deployment for performance reasons. Asserts are not archaic. I'm sorry to sound harsh, but this answer is not remotely helpful to the original question, nor correct.
-
markand over 8 yearsNote that you can use std::nothrow for that.
-
ar2015 about 8 yearshow to use
goto
wisely? -
underscore_d about 8 years@ar2015 Find one of the absurdly contrived patterns that some people recommend to avoid
goto
for purely religious reasons, then just usegoto
rather than obfuscating what you're doing. In other words: if you can prove you really needgoto
, and the only alternative is to enact a load of pointless scaffolding that ultimately does the same thing but without alterting the Goto Police... then just usegoto
. Of course, a precondition of this is the bit "if you can prove you really needgoto
". Often, people don't. That still doesn't mean it's inherently a Bad Thing. -
malat about 8 years
goto
is used in linux kernel for code cleanup -
Gaspa79 over 3 yearsThe only place so far I found goto to be absolutely superior is to create an abort-retry-ignore logic with user confirmation. It makes the code much easier to read and write in that case (this is just an opinion). The other not-so-superior case is to break outside switch statements to another switch statement in languages like C# that do not allow fallthrough.