- asserts considered harmful - 10 Updates
- TDD can be useful even when it doesn't achieve what you want - 1 Update
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Feb 24 05:52PM On 24/02/2016 02:47, Öö Tiib wrote: > That 'vector::at()' is likely for cases when out of range index can be > result of valid processing for example it was read from some potentially > dirty stream. Otherwise it is better to 'assert' and to use []. That would be an inappropriate use of vector::at(). Invalid user input is a runtime error not a logic error and passing an invalid index to vector::at() is a logic error evidenced by the fact that std::out_of_range is derived from std::logic_error. The correct thing to do is validate your input first and then you can use vector::operator[]() instead of vector::at() which in my opinion is redundantly defensive as we should design our code in such away that logic errors are mitigated against. /Flibble |
"Öö Tiib" <ootiib@hot.ee>: Feb 24 11:14AM -0800 On Wednesday, 24 February 2016 19:52:18 UTC+2, Mr Flibble wrote: > vector::operator[]() instead of vector::at() which in my opinion is > redundantly defensive as we should design our code in such away that > logic errors are mitigated against. Who said that potentially dirty stream comes from human? World is full of automated dirty stream sources. That 'at()' *is* validating input and exception is perfectly fine since likely a whole transaction containing invalid index has to be canceled and rejected; there's no need to validate it any further. I agree that 'at()' of most containers is rarely useful, instead assert and [] are common but it was you who brought it up. |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Feb 24 07:42PM On 24/02/2016 19:14, Öö Tiib wrote: > validate it any further. I agree that 'at()' of most containers is > rarely useful, instead assert and [] are common but it was you who > brought it up. Who said "user" was a human? It still makes no difference: you should still validate your input whatever its source and at() is not the place to do that validation as propagating a logic error exception is inappropriate for invalid runtime data. /Flibble |
Cholo Lennon <chololennon@hotmail.com>: Feb 24 04:49PM -0300 On 02/23/2016 07:27 PM, Ian Collins wrote: >> undetected bugs in a release build manifesting as undefined behaviour >> that doesn't cause a straight crash but does something more serious. > So don't change NDEBUG in your release builds. Long time ago I had to deal with a nasty assert enabled in release builds. From time to time (very seldom) our application crashed in a production environment. The application used an internal dynamic library which in turns used a third party library. The latter had an assert for an unusual situation (a network packet not recognized). The author decided that instead of just ignoring the packet o logging it, he had to assert. It was a bad decision combined with asserts enabled by default in release build. assert (I'm talking about C assert) must be used carefully and IMHO must not be enabled in release. If you need to report unsusual situations use exceptions or create a new assert macro on top of C++ exceptions. In my personal case I'm using asserts for pre/post conditions (expects/ensures) in a similar way to thoses described here: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md (from the link see "State preconditions (if any)" and "State postconditions") My macros are build on top of C++ exceptions and can be enabled/disabled in release builds. Regards -- Cholo Lennon Bs.As. ARG |
"Öö Tiib" <ootiib@hot.ee>: Feb 24 12:58PM -0800 On Wednesday, 24 February 2016 21:42:20 UTC+2, Mr Flibble wrote: > still validate your input whatever its source and at() is not the place > to do that validation as propagating a logic error exception is > inappropriate for invalid runtime data. Where it is written that I should use "logic error" for reporting defects in my code? I use unit tests, 'static_assert' and 'assert' to check for defects in my code. Every of those is stop the show and back to drawing board, it is not "exceptional situation" that I made a defect. I make one every hour or so, it is part of work. I do not know if the index was produced run time by that "user" or was carved into rock like that since stone age. It is index that does not make sense, so it is violating logical preconditions and data invariants and so is logic error. "Out of range" is clearest explanation of the error. As contrast writing code that checks and throws something else like "range error" on my own instead of using 'at()' would be wrong. Wrong exception, pointless duplication of already existing standard feature and needless bloat. |
Vir Campestris <vir.campestris@invalid.invalid>: Feb 24 09:27PM On 23/02/2016 23:20, Mr Flibble wrote: > Not true: std::logic_error is meant for coding errors including > incorrect assumptions. One should derive custom exceptions from > std::logic_error and throw these instead of asserting. That doesn't mean assert is bad. Assert in debug builds can cause your program to blow up with a nice dump that's easy for you to sort out - the program has made no attempt to clean up before reporting the problem. But when the code is out in the field - imagine a word processor. The use has been typing for an hour, and hasn't saved. He inserts some funny field, the program asserts, and he loses his edits. Or the program doesn't assert, does its best to recover the error, forgets how it got in that situation - but there's at least a chance of saving the document. Also enough asserts will be big and slow. Just as I turn on the optimiser in the compiler before release, I disable lots of debug logging - and asserts. Andy |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Feb 24 09:49PM On 24/02/2016 20:58, Öö Tiib wrote: > not make sense, so it is violating logical preconditions and data > invariants and so is logic error. "Out of range" is clearest > explanation of the error. Why are you being so obtuse? If you let at() throw then you ARE using a logic error for something that is not a logic error. YOU ARE DOING IT WRONG. > "range error" on my own instead of using 'at()' would be wrong. Wrong > exception, pointless duplication of already existing standard feature > and needless bloat. Nobody is suggesting that .. STOP BEING SO OBTUSE. /Flibble |
Ian Collins <ian-news@hotmail.com>: Feb 25 10:59AM +1300 Vir Campestris wrote: > Also enough asserts will be big and slow. Just as I turn on the > optimiser in the compiler before release, I disable lots of debug > logging - and asserts. A reasonable counter example to your word processor is a compiler. If the code generator hits an "impossible" condition it can't handle, bailing is the only option. Even your word processor, if it realised its internal state was corrupt, would have little choice but to abort. To do anything else would be courting disaster. The key point Flibble either doesn't get (or more likely, chooses to ignore) is asserts really should be used for exceptional conditions *from which there is no recovery*. In those situations you (as a developer) need as much information about the state of the application as you can get, hence aborting with a core dump or (as on OSX) an opportunity for the user to send a crash report. These asserts should never be removed from the code. Throwing an exception when you know something (possibly the stack) is corrupt is madness. -- Ian Collins |
"Öö Tiib" <ootiib@hot.ee>: Feb 24 02:03PM -0800 On Wednesday, 24 February 2016 23:49:28 UTC+2, Mr Flibble wrote: > > explanation of the error. > Why are you being so obtuse? If you let at() throw then you ARE using a > logic error for something that is not a logic error. YOU ARE DOING IT WRONG. You are doing it wrong. You are asserting something baldly and then discussing mine mental capabilities instead of discussing the points that I made and the detail of it you consider incorrect. > > exception, pointless duplication of already existing standard feature > > and needless bloat. > Nobody is suggesting that .. STOP BEING SO OBTUSE. You are mirroring. Everybody tells you that stop asserting that "sky is blue" crap baldly and obtusely. Instead elaborate what you are suggesting and be constructive. |
"Öö Tiib" <ootiib@hot.ee>: Feb 24 02:13PM -0800 On Wednesday, 24 February 2016 23:27:53 UTC+2, Vir Campestris wrote: > field, the program asserts, and he loses his edits. Or the program > doesn't assert, does its best to recover the error, forgets how it got > in that situation - but there's at least a chance of saving the document. Aborting in unexpected state is likely safest choice for any serious software. Most word processors on market keep documents saved all time. Try. Turn computer's power off and on then run the word processor again. Majority of those tell that document was recovered (or couple of documents). If you really have one that does not do that then uninstall it and download LibreOffice or something. Avoiding aborting program on case of error makes sense on case of entertainment software because little defect in art or something can keep it enjoyable but a crash seriously annoys. |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Feb 24 06:05PM On 24/02/2016 17:12, Richard wrote: > As a result I get better designs from my code and the code I produce > is consistent with the advice from leaders in the field of > programming, both specific to C++ and more generally. I doubt that very much. Designing software by fixing failing tests is not software design at all and for this reason I suspect the quality of your TDD driven designs is very poor. *Good* software design is: 1) Thinking about system architecture; 2) Based on 1) designing the software architecture; 3) Thinking about abstractions; 4) Based on 2) and 3) designing interfaces; 5) Based on 3) and 4) designing class hierarchies and concrete classes; 6) Designing object hierarchies, and object lifetime envelopes. *Good* software design is not: 1) Make a failing test pass. Obviously requirements gathering and analysis is a given. /Flibble |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment