May 31, 2006 Re: assert(condition[, message]) patch | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter Bright wrote:
> braddr@puremagic.com wrote:
>> I have been toying with D to bring myself up to speed and I found myself writing
>> a lot of unit tests, always a good thing. In those unit tests I found myself
>> writing a lot of blocks like:
>>
>> if (cond)
>> {
>> writefln("some debugging output to make my life easier");
>> assert(false);
>> }
>>
>> I know many don't like unit tests to have output, but I do.
>
> Why not:
>
> assert(!cond); // some debugging output to make my life easier
>
> ? You'll need to go look at the source anyway when the assert trips, so what advantage is there to print the comment?
Some applications ship with asserts left on, and the more information the user has about why the application just halted the better. As others have noted, an optional message also allows state information to be conveyed, which can be useful in the absence of a core dump.
Sean
|
May 31, 2006 Re: assert(condition[, message]) patch | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Miller | Chris Miller wrote: > On Wed, 31 May 2006 13:01:24 -0400, Walter Bright >> ? You'll need to go look at the source anyway when the assert trips, so what advantage is there to print the comment? > > How about when you have many versions of the program and source. Sure if you backup regularly and save them all you can eventually figure out which assert, but a message usually lets you find it in seconds. I'm not sure what there is to figure out, it gives the source file and line number. If you're using a decent IDE, it'll even automatically bring up the source file and position the cursor on the offending line. > I'd also be satisfied if it only used the assert expression as this message (and a trick could be used if one really wants: assert(foo && "my message");). |
May 31, 2006 Re: assert(condition[, message]) patch | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Wed, 31 May 2006 17:55:51 -0400, Walter Bright <newshound@digitalmars.com> wrote:
> Chris Miller wrote:
>> On Wed, 31 May 2006 13:01:24 -0400, Walter Bright
>>> ? You'll need to go look at the source anyway when the assert trips, so what advantage is there to print the comment?
>> How about when you have many versions of the program and source. Sure if you backup regularly and save them all you can eventually figure out which assert, but a message usually lets you find it in seconds.
>
> I'm not sure what there is to figure out, it gives the source file and line number. If you're using a decent IDE, it'll even automatically bring up the source file and position the cursor on the offending line.
>
"How about when you have many versions of the program and source" == source files have been modified; lines don't "line up" unless you coordinate the version and dig it up.
|
May 31, 2006 Re: assert(condition[, message]) patch | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | On Thu, 01 Jun 2006 04:38:50 +1000, Sean Kelly <sean@f4.ca> wrote: > Walter Bright wrote: >> braddr@puremagic.com wrote: >>> I have been toying with D to bring myself up to speed and I found myself writing >>> a lot of unit tests, always a good thing. In those unit tests I found myself >>> writing a lot of blocks like: >>> >>> if (cond) >>> { >>> writefln("some debugging output to make my life easier"); >>> assert(false); >>> } >>> >>> I know many don't like unit tests to have output, but I do. >> Why not: >> assert(!cond); // some debugging output to make my life easier >> ? You'll need to go look at the source anyway when the assert trips, so what advantage is there to print the comment? > > Some applications ship with asserts left on, and the more information the user has about why the application just halted the better. As others have noted, an optional message also allows state information to be conveyed, which can be useful in the absence of a core dump. And this is a deployment/development strategy that is flawed. It would be better to ship a product without asserts turned on, but if you have to show internal issues to a customer then don't use asserts - use exceptions or similar to do this at run time. Just use asserts for quality assurance prior to shipping. For me, the golden rule with D is don't use asserts to report errors in production releases. -- Derek Parnell Melbourne, Australia |
May 31, 2006 Re: assert(condition[, message]) patch | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lars Ivar Igesund | Lars Ivar Igesund wrote: > Because not all the users will have access to the source, or be inclined to > see it. Unless the user get's a readable/understandable assert message > he/she might not get enough information to actually reproduce a test case > for the developer to peruse. > > Walter, this is a no-brainer, please put it in. ++votes; /+ when you release your app to some testing team, you might want to leave asserts in. While an error message containing the line number and filename could be helpful, an additional message could be priceless. E.g. assert(fileNameContainsNoSpaces(foo)); won't tell you that the 'foo' really was something like '^&^34 5+23 3(43D678[SAFer6_[]' which might mean some mem corruption or forgetting a .dup somewhere in your code. You'd instead go searching for some logic problems that wouldn't solve the problem. +/ -- Tomasz Stachowiak /+ a.k.a. h3r3tic +/ |
May 31, 2006 Re: assert(condition[, message]) patch | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | Derek Parnell wrote: > On Thu, 01 Jun 2006 04:38:50 +1000, Sean Kelly <sean@f4.ca> wrote: > >> Some applications ship with asserts left on, and the more information the user has about why the application just halted the better. As others have noted, an optional message also allows state information to be conveyed, which can be useful in the absence of a core dump. > > And this is a deployment/development strategy that is flawed. It would be better to ship a product without asserts turned on, but if you have to show internal issues to a customer then don't use asserts - use exceptions or similar to do this at run time. Just use asserts for quality assurance prior to shipping. > > For me, the golden rule with D is don't use asserts to report errors in production releases. > An assert is just syntactic sugar for something like: if(!(cond)) throw new AssertError(__FILE__":"~itoa!(__LINE__)~" Assert ERROR") so they are exceptions. As to not reporting asserts to the user, how about making asserts go to a special Stream object that can be redirected to a file or something (if it goes to stderr we're most of the way there). That with a backtrace log could make for a vary powerful bug hunting tool. |
May 31, 2006 Re: assert(condition[, message]) patch | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | Derek Parnell wrote:
> On Thu, 01 Jun 2006 04:38:50 +1000, Sean Kelly <sean@f4.ca> wrote:
>
>> Walter Bright wrote:
>>> braddr@puremagic.com wrote:
>>>> I have been toying with D to bring myself up to speed and I found myself writing
>>>> a lot of unit tests, always a good thing. In those unit tests I found myself
>>>> writing a lot of blocks like:
>>>>
>>>> if (cond)
>>>> {
>>>> writefln("some debugging output to make my life easier");
>>>> assert(false);
>>>> }
>>>>
>>>> I know many don't like unit tests to have output, but I do.
>>> Why not:
>>> assert(!cond); // some debugging output to make my life easier
>>> ? You'll need to go look at the source anyway when the assert trips, so what advantage is there to print the comment?
>>
>> Some applications ship with asserts left on, and the more information the user has about why the application just halted the better. As others have noted, an optional message also allows state information to be conveyed, which can be useful in the absence of a core dump.
>
> And this is a deployment/development strategy that is flawed. It would be better to ship a product without asserts turned on, but if you have to show internal issues to a customer then don't use asserts - use exceptions or similar to do this at run time. Just use asserts for quality assurance prior to shipping.
There's a popular argument connected to contract programming which says that it makes no sense to test with contracts enabled and disable them in the release code. I'd prefer not to take sides here, but I do think that in instances where the application should halt because a condition has not been met, an assert should be used. If the programmer would prefer that the user not see file and line information, he can easily catch the error in main, report it however he wants to, and then return.
That said, my real goal here is merely to make assert a bit more flexible so users aren't inclined to roll their own error handling routines simply because they want to provide context information. The above example just happened to be the first I though of.
Sean
|
June 01, 2006 Re: assert(condition[, message]) patch | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | Sean Kelly wrote:
[snip]
> There's a popular argument connected to contract programming which says that it makes no sense to test with contracts enabled and disable them in the release code. I'd prefer not to take sides here, but I do think that in instances where the application should halt because a condition has not been met, an assert should be used. If the programmer would prefer that the user not see file and line information, he can easily catch the error in main, report it however he wants to, and then return.
>
> That said, my real goal here is merely to make assert a bit more flexible so users aren't inclined to roll their own error handling routines simply because they want to provide context information.
Amen.
I find it surprising that the dmd support code still makes it awkward to add file & line number info to all exceptions. Asserts are no less vague in this respect. One has to wonder if this is deliberate or not?
On the other hand, Ares has provided for optional Exception file & line ctor arguments for at least a year.
Seems quite clear that people *want* more flexible assert and exception reporting. It also seems clear that everyone will roll their own if it's not provided as basic functionality. I certainly would like to add it to library code, since I suspect most folk would appreciate having it there :)
Is there a contrary argument or position? I mean, is there some negative aspect of enabling (optional) better error reporting?
|
June 01, 2006 Re: assert(condition[, message]) patch | ||||
---|---|---|---|---|
| ||||
Posted in reply to kris | On Wed, 31 May 2006 17:05:16 -0700, kris wrote: > Sean Kelly wrote: > [snip] >> There's a popular argument connected to contract programming which says that it makes no sense to test with contracts enabled and disable them in the release code. I'd prefer not to take sides here, but I do think that in instances where the application should halt because a condition has not been met, an assert should be used. If the programmer would prefer that the user not see file and line information, he can easily catch the error in main, report it however he wants to, and then return. >> >> That said, my real goal here is merely to make assert a bit more flexible so users aren't inclined to roll their own error handling routines simply because they want to provide context information. > > Amen. > > I find it surprising that the dmd support code still makes it awkward to add file & line number info to all exceptions. Asserts are no less vague in this respect. One has to wonder if this is deliberate or not? > > On the other hand, Ares has provided for optional Exception file & line ctor arguments for at least a year. > > Seems quite clear that people *want* more flexible assert and exception reporting. It also seems clear that everyone will roll their own if it's not provided as basic functionality. I certainly would like to add it to library code, since I suspect most folk would appreciate having it there :) > > Is there a contrary argument or position? I mean, is there some negative aspect of enabling (optional) better error reporting? I suspect that this is the real issue. Namely that it is possible to provide additional information at runtime when an 'assert' fires, but to do so is awkward in comparison to a simple "assert( <Expression> )" statement. One could always do something like ... // ---- file: massert.d ---- private import std.string; void myassert(bool res, char[] f, long l, char[] msg) { if (!res) { throw new Exception(std.string.format("ASSERT in File: %s(%s), %s", f, l, msg)); } } // --- file: myapp.d ----- import massert; import std.string; void main(char[][] pArgs) { myassert( pArgs.length >= 2, __FILE__, __LINE__, "Not enough args supplied" ); myassert( pArgs[1].length >= 2, __FILE__, __LINE__, std.string.format("Arg1 '%s' too short", pArgs[1]) ); } but I concede that this is not pretty. -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocracy!" 1/06/2006 10:55:52 AM |
June 01, 2006 Re: assert(condition[, message]) patch | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter,
My most common use for having this is simple.
Consider an open source software. Various versions of the same software are in use, each with different patches applied.
Let's say this happened to dmd, or gdc. Let's say a compiler error occurred... this:
expression.c(379)
Because a patch has been applied to expression.c - a rather long one adding support for "x ?: y" or something else like that (maybe a bad example) the error actually shows:
expression.c(518)
The user, who has this patch, does not really know much about programming, and reports it to the original software developer. Eventually, after initial confusion, it becomes clear that patches are involved, and these are listed. Eventually, the bug can be tracked down.
With a compiler, this is really not a common thing. But with many other softwares, this is VERY common. I have had a huge amount of experience with exactly this problem, although not in D.
It was not fun, and caused finding bugs, searching for solutions to common problems, and everything much much more difficult and time consuming.
Error messages in this software were eventually revamped to be logged with more extensive information. It became rapidly easier to debug the software, and make it robust and bug free. Searching for errors was no longer done by line number, resulting in a much higher rate of return - which meant our support team was much less bogged down by those requests.
I realize it doesn't benefit DMD much, but having some way to give more information than a line number (which, to some projects, is about as useful as dumping the value of a pointer at runtime) is extremely useful for many sorts of open source softwares.
It's also useless when you have people using/testing nightlies or frequent beta releases, a practice that generally helps to improve overall release quality. You can't even tag the assert with a release tag or revision. Even if not for the patches...
As it is, I guess the solution is simple. Don't use assert, it's almost useless for any robust application development. Roll your own instead, e.g. using if as Brad suggested.
-[Unknown]
> braddr@puremagic.com wrote:
>> I have been toying with D to bring myself up to speed and I found myself writing
>> a lot of unit tests, always a good thing. In those unit tests I found myself
>> writing a lot of blocks like:
>>
>> if (cond)
>> {
>> writefln("some debugging output to make my life easier");
>> assert(false);
>> }
>>
>> I know many don't like unit tests to have output, but I do.
>
> Why not:
>
> assert(!cond); // some debugging output to make my life easier
>
> ? You'll need to go look at the source anyway when the assert trips, so what advantage is there to print the comment?
|
Copyright © 1999-2021 by the D Language Foundation