www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - assert(condition[, message]) patch

reply braddr puremagic.com writes:
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.  To simplify this,
I've created a patch for gdc/dmd to allow this syntax instead:

assert(cond, "some optional debugging output to make my life easier");

http://www.puremagic.com/~braddr/d/assert-optional-message-0.1.diff
http://www.puremagic.com/~braddr/d/assert-test.d

I've run this through dstress with no regressions.

Anyone wanna give it a whirl?

Later,
Brad
Feb 01 2006
next sibling parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
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.  To simplify this,
 I've created a patch for gdc/dmd to allow this syntax instead:
 
 assert(cond, "some optional debugging output to make my life easier");
 
 http://www.puremagic.com/~braddr/d/assert-optional-message-0.1.diff
 http://www.puremagic.com/~braddr/d/assert-test.d
 
 I've run this through dstress with no regressions.
 
 Anyone wanna give it a whirl?
 
 Later,
 Brad
 
 

How can we install/apply the patch?
Feb 01 2006
parent braddr puremagic.com writes:
In article <drs0sb$2vhj$1 digitaldaemon.com>, Hasan Aljudy says...
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.  To simplify this,
 I've created a patch for gdc/dmd to allow this syntax instead:
 
 assert(cond, "some optional debugging output to make my life easier");
 
 http://www.puremagic.com/~braddr/d/assert-optional-message-0.1.diff
 http://www.puremagic.com/~braddr/d/assert-test.d
 
 I've run this through dstress with no regressions.
 
 Anyone wanna give it a whirl?
 
 Later,
 Brad
 
 

How can we install/apply the patch?

Save the .diff to a file, use the standard unix tool 'patch' to apply it to a gcc+gdc source tree from the gcc directory, and rebuild gdc. Later, Brad
Feb 01 2006
prev sibling next sibling parent reply "Unknown W. Brackets" <unknown simplemachines.org> writes:
Does this effect static asserts?  Currently, you can do this with them:

static assert ("Some message.", 0);

This is because it is passed an expression, and so "", 0 just evaluates 
to 0.  But it does display the whole thing.

-[Unknown]


 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.  To simplify this,
 I've created a patch for gdc/dmd to allow this syntax instead:
 
 assert(cond, "some optional debugging output to make my life easier");
 
 http://www.puremagic.com/~braddr/d/assert-optional-message-0.1.diff
 http://www.puremagic.com/~braddr/d/assert-test.d
 
 I've run this through dstress with no regressions.
 
 Anyone wanna give it a whirl?
 
 Later,
 Brad
 
 

Feb 01 2006
parent braddr puremagic.com writes:
In article <drs52m$mu$1 digitaldaemon.com>, Unknown W. Brackets says...

 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.  To simplify this,
 I've created a patch for gdc/dmd to allow this syntax instead:
 
 assert(cond, "some optional debugging output to make my life easier");
 
 http://www.puremagic.com/~braddr/d/assert-optional-message-0.1.diff
 http://www.puremagic.com/~braddr/d/assert-test.d
 
 I've run this through dstress with no regressions.
 
 Anyone wanna give it a whirl?
 
 Later,
 Brad

Does this effect static asserts? Currently, you can do this with them: static assert ("Some message.", 0); This is because it is passed an expression, and so "", 0 just evaluates to 0. But it does display the whole thing. -[Unknown]

<peeking at the code...> Looks like assert and static assert are handled by completely different blocks of code, completely. so, static assert(...) is unchanged. Later, Brad
Feb 01 2006
prev sibling next sibling parent Yves Jacoby <kloune gmail.com> writes:
On Thu, 02 Feb 2006 01:35:20 +0000, braddr 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.  To simplify this,
 I've created a patch for gdc/dmd to allow this syntax instead:
 
 assert(cond, "some optional debugging output to make my life easier");
 
 http://www.puremagic.com/~braddr/d/assert-optional-message-0.1.diff
 http://www.puremagic.com/~braddr/d/assert-test.d
 
 I've run this through dstress with no regressions.
 
 Anyone wanna give it a whirl?
 
 Later,
 Brad

Simply "Thank you". Great thing.
Feb 02 2006
prev sibling next sibling parent =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
braddr wrote:

 I know many don't like unit tests to have output, but I do.  To simplify this,
 I've created a patch for gdc/dmd to allow this syntax instead:
 
 assert(cond, "some optional debugging output to make my life easier");

Excellent, I would be happy to include this in "gdcmac" for instance. (if there aren't any objections to including "non-offical" D patches into the compiler, already have a few necessary-for-portability ones) Too bad that it doesn't get past the: assert(false, "Walter didn't like it"); --anders
Feb 02 2006
prev sibling next sibling parent Psi Oddech <Psi_member pathlink.com> writes:
It's been a while since I've programmed something but I used something along the
lines of assert(condition && "whatever") or assert(condition &&
printf("whatever")), whichever worked.

In article <drrnko$2onm$1 digitaldaemon.com>, braddr puremagic.com says...
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.  To simplify this,
I've created a patch for gdc/dmd to allow this syntax instead:

assert(cond, "some optional debugging output to make my life easier");

http://www.puremagic.com/~braddr/d/assert-optional-message-0.1.diff
http://www.puremagic.com/~braddr/d/assert-test.d

I've run this through dstress with no regressions.

Anyone wanna give it a whirl?

Later,
Brad

Feb 02 2006
prev sibling next sibling parent reply braddr puremagic.com writes:
In article <drrnko$2onm$1 digitaldaemon.com>, braddr puremagic.com says...
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.  To simplify this,
I've created a patch for gdc/dmd to allow this syntax instead:

assert(cond, "some optional debugging output to make my life easier");

http://www.puremagic.com/~braddr/d/assert-optional-message-0.1.diff
http://www.puremagic.com/~braddr/d/assert-test.d

I've run this through dstress with no regressions.

Anyone wanna give it a whirl?

Later,
Brad

I was just about to start bringing this patch up to work with current dmd and gdc but decided I should ask first: Is anyone using it with gdc 0.17? Would anyone use it if I freshened it up? Walter, would you be interested / willing to incorporate the parser part into dmd and support the feature in dmd? I've seen a couple alternatives suggested, but they've all been somewhat hacky, imho. Later, Brad
May 30 2006
next sibling parent reply akcom <CppCoder gmail.com> writes:
braddr puremagic.com wrote:
 In article <drrnko$2onm$1 digitaldaemon.com>, braddr puremagic.com says...
 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.  To simplify this,
 I've created a patch for gdc/dmd to allow this syntax instead:

 assert(cond, "some optional debugging output to make my life easier");

 http://www.puremagic.com/~braddr/d/assert-optional-message-0.1.diff
 http://www.puremagic.com/~braddr/d/assert-test.d

 I've run this through dstress with no regressions.

 Anyone wanna give it a whirl?

 Later,
 Brad

I was just about to start bringing this patch up to work with current dmd and gdc but decided I should ask first: Is anyone using it with gdc 0.17? Would anyone use it if I freshened it up? Walter, would you be interested / willing to incorporate the parser part into dmd and support the feature in dmd? I've seen a couple alternatives suggested, but they've all been somewhat hacky, imho. Later, Brad

must consider that the assert( statementToTest ) would give you the line that threw the assert, which makes a message a bit less important. Although, on the other hand, if someone (ie not someone who wrote the code) were to see the assert and check the given line, it probably wouldn't mean too much to them, whereas being able to see a message associated with it would be a bit more useful. I'd definitely give the mod a whirl.
May 30 2006
parent reply BCS <BCS_member pathlink.com> writes:
In article <e5im92$hlo$2 digitaldaemon.com>, akcom says...

Just my thoughts, I think it's definitely got some merits, although one 
must consider that the assert( statementToTest ) would give you the line 
that threw the assert, which makes a message a bit less important. 

if the message is non static then a lot of info can be printed. assert(str.length < 5, `the string "` ~ str ~ `" is more than 5 char long"); I'll vote for this.
May 30 2006
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
BCS wrote:
 In article <e5im92$hlo$2 digitaldaemon.com>, akcom says...
 [...]
 Just my thoughts, I think it's definitely got some merits, although one 
 must consider that the assert( statementToTest ) would give you the line 
 that threw the assert, which makes a message a bit less important. 

if the message is non static then a lot of info can be printed. assert(str.length < 5, `the string "` ~ str ~ `" is more than 5 char long"); I'll vote for this.

I like the idea, but here's a better one that I could have used when testing my MMX routines: # ubyte[] a = new ubyte[4096]; // src1 # ubyte[] b = new ubyte[4096]; // src2 # ubyte[] c = new ubyte[4096]; // dst # ubyte[] d = new ubyte[4096]; // result calculated "long hand" # # // ... # # adds(a, b, c); # assert(c == d); Working out *why* it's asserted is no fun whatsoever. YES it's told you there's a bug, but in this case, it hasn't even told you what that bug is. Just that it exists. In this case, using a message would help; I could tell myself where the assert had failed. Even better would be a few more asserts: # assertArrayEqual(c, d); Which might print: AssertError foo.d line 2001: mismatch at element 42: expected "6", got "9". I would have KILLED for that a few weeks ago :) I'd implement that myself, except that `assert` seems to be the ONLY statement in D that automatically passes the source file and line number to the exception. Walter: is there any technical reason why we can't get Exceptions to automatically have source file and line number assigned when instantiated? Hmm. Seem to have gone off topic somewhat. Gomen. -- Daniel -- Unlike Knuth, I have neither proven or tried the above; it may not even make sense. v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
May 30 2006
parent reply Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
Daniel Keep wrote:
 
 BCS wrote:
 In article <e5im92$hlo$2 digitaldaemon.com>, akcom says...
 [...]
 Just my thoughts, I think it's definitely got some merits, although one 
 must consider that the assert( statementToTest ) would give you the line 
 that threw the assert, which makes a message a bit less important. 

assert(str.length < 5, `the string "` ~ str ~ `" is more than 5 char long"); I'll vote for this.

I like the idea, but here's a better one that I could have used when testing my MMX routines: # ubyte[] a = new ubyte[4096]; // src1 # ubyte[] b = new ubyte[4096]; // src2 # ubyte[] c = new ubyte[4096]; // dst # ubyte[] d = new ubyte[4096]; // result calculated "long hand" # # // ... # # adds(a, b, c); # assert(c == d); Working out *why* it's asserted is no fun whatsoever. YES it's told you there's a bug, but in this case, it hasn't even told you what that bug is. Just that it exists. In this case, using a message would help; I could tell myself where the assert had failed. Even better would be a few more asserts: # assertArrayEqual(c, d); Which might print: AssertError foo.d line 2001: mismatch at element 42: expected "6", got "9". I would have KILLED for that a few weeks ago :) I'd implement that myself, except that `assert` seems to be the ONLY statement in D that automatically passes the source file and line number to the exception. Walter: is there any technical reason why we can't get Exceptions to automatically have source file and line number assigned when instantiated?

You mean when thrown, no?
 Hmm.  Seem to have gone off topic somewhat.  Gomen.
 
 	-- Daniel
 

-- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
May 31 2006
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Bruno Medeiros wrote:
 Daniel Keep wrote:
 BCS wrote:
 In article <e5im92$hlo$2 digitaldaemon.com>, akcom says...
 [...]
 Just my thoughts, I think it's definitely got some merits, although
 one must consider that the assert( statementToTest ) would give you
 the line that threw the assert, which makes a message a bit less
 important. 

assert(str.length < 5, `the string "` ~ str ~ `" is more than 5 char long"); I'll vote for this.

I like the idea, but here's a better one that I could have used when testing my MMX routines: # ubyte[] a = new ubyte[4096]; // src1 # ubyte[] b = new ubyte[4096]; // src2 # ubyte[] c = new ubyte[4096]; // dst # ubyte[] d = new ubyte[4096]; // result calculated "long hand" # # // ... # # adds(a, b, c); # assert(c == d); Working out *why* it's asserted is no fun whatsoever. YES it's told you there's a bug, but in this case, it hasn't even told you what that bug is. Just that it exists. In this case, using a message would help; I could tell myself where the assert had failed. Even better would be a few more asserts: # assertArrayEqual(c, d); Which might print: AssertError foo.d line 2001: mismatch at element 42: expected "6", got "9". I would have KILLED for that a few weeks ago :) I'd implement that myself, except that `assert` seems to be the ONLY statement in D that automatically passes the source file and line number to the exception. Walter: is there any technical reason why we can't get Exceptions to automatically have source file and line number assigned when instantiated?

You mean when thrown, no?
 Hmm.  Seem to have gone off topic somewhat.  Gomen.

     -- Daniel


# try # { # // ... # } # catch( Exception e ) # { # // Hmm... nevermind # throw e; # } See the problem? :P -- Unlike Knuth, I have neither proven or tried the above; it may not even make sense. v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
May 31 2006
parent Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
Daniel Keep wrote:
 
 Bruno Medeiros wrote:
 Daniel Keep wrote:
 BCS wrote:
 In article <e5im92$hlo$2 digitaldaemon.com>, akcom says...
 [...]
 Just my thoughts, I think it's definitely got some merits, although
 one must consider that the assert( statementToTest ) would give you
 the line that threw the assert, which makes a message a bit less
 important. 

assert(str.length < 5, `the string "` ~ str ~ `" is more than 5 char long"); I'll vote for this.

testing my MMX routines: # ubyte[] a = new ubyte[4096]; // src1 # ubyte[] b = new ubyte[4096]; // src2 # ubyte[] c = new ubyte[4096]; // dst # ubyte[] d = new ubyte[4096]; // result calculated "long hand" # # // ... # # adds(a, b, c); # assert(c == d); Working out *why* it's asserted is no fun whatsoever. YES it's told you there's a bug, but in this case, it hasn't even told you what that bug is. Just that it exists. In this case, using a message would help; I could tell myself where the assert had failed. Even better would be a few more asserts: # assertArrayEqual(c, d); Which might print: AssertError foo.d line 2001: mismatch at element 42: expected "6", got "9". I would have KILLED for that a few weeks ago :) I'd implement that myself, except that `assert` seems to be the ONLY statement in D that automatically passes the source file and line number to the exception. Walter: is there any technical reason why we can't get Exceptions to automatically have source file and line number assigned when instantiated?

 Hmm.  Seem to have gone off topic somewhat.  Gomen.

     -- Daniel


# try # { # // ... # } # catch( Exception e ) # { # // Hmm... nevermind # throw e; # } See the problem? :P

Easily solvable I think. 'throw' will only fill file-line info once for a given exception (that is, it fills only if the exception hasn't that info already). But now that you mention that idiom, I wonder how other languages deal with that. I'll have to check it out -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Jun 02 2006
prev sibling parent Sean Kelly <sean f4.ca> writes:
braddr puremagic.com wrote:
 
 I was just about to start bringing this patch up to work with current dmd and
 gdc but decided I should ask first:
 
 Is anyone using it with gdc 0.17?
 Would anyone use it if I freshened it up?
 Walter, would you be interested / willing to incorporate the parser part into
 dmd and support the feature in dmd?

Assuming the feature were added to DMD I'd definitely use it, but I've avoided it to date as I dislike language extensions. Sean
May 30 2006
prev sibling parent reply Walter Bright <newshound digitalmars.com> writes:
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?
May 31 2006
next sibling parent BCS <BCS_member pathlink.com> writes:
In article <e5ki8s$jfc$1 digitaldaemon.com>, Walter Bright says...
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?

a little run time info could be realy helpfull. # assert(str.length < 5, `the string "` ~ str ~ `" is more than 5 char long`); or in the case someone was talking about (MMX stuff) .. char[] assertMsg assert(compArray(c,d,assertMsg), assertMsg); .. bool compArray(int[] a, int[] b, inout char[] msg) { if(a==b) return true; if(a.length != b.length) { msg = "Unequal length"; return false; } foreach(int i, int j; a) if(a[i] != b[i]) { msg = "element #" ~ toString(i) ~ " unequal"; return false; } msg = "somthings wrong"; return false; }
May 31 2006
prev sibling next sibling parent Brad Roberts <braddr puremagic.com> writes:
On Wed, 31 May 2006, 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?

Often it saves one cycle through the debugger by the expediency of having actual information about what caused the assert, more than just 'something broke here' that a plain assertion violation causes today. Take a look at some code I wrote where the unit tests use this feature: http://www.puremagic.com/~braddr/d/interned_string.d A comment can't convey state, just intent. I've reapplied the referenced patch to dmd/gdc and it works when used properly. However, exactly like it was before, it's got a number of bugs when used improperly. I need to learn more about dmd and gdc both to fix the thing to be robust enough to actually merge in. Later, Brad
May 31 2006
prev sibling next sibling parent reply "Chris Miller" <chris dprogramming.com> writes:
On Wed, 31 May 2006 13:01:24 -0400, Walter Bright  
<newshound digitalmars.com> 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?

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'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
parent reply Walter Bright <newshound digitalmars.com> writes:
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
parent "Chris Miller" <chris dprogramming.com> writes:
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?

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
prev sibling next sibling parent reply Lars Ivar Igesund <larsivar igesund.net> writes:
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?

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. -- Lars Ivar Igesund blog at http://larsivi.net DSource & #D: larsivi
May 31 2006
parent reply Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
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
parent reply Joseph Lisee <jlisee umd.edu> writes:
In article <e5l5v8$1g7j$1 digitaldaemon.com>,
 Tom S <h3r3tic remove.mat.uni.torun.pl> wrote:

 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. +/

I vote for the assert(condition, "msg"), construct as well. CXX Test and JUnit have spoiled me. You can't even do assert(1 == 0 && "The laws of math have been changed"), which is trick I use in the C++ all the time. Is having a message with the assert going to hurt anything? -Joseph Lisee
Jul 31 2006
parent reply Sean Kelly <sean f4.ca> writes:
Joseph Lisee wrote:
 In article <e5l5v8$1g7j$1 digitaldaemon.com>,
  Tom S <h3r3tic remove.mat.uni.torun.pl> wrote:
 
 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.

/+ 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. +/

I vote for the assert(condition, "msg"), construct as well.

This feature was added a number of builds ago. Sean
Jul 31 2006
parent reply Joseph Lisee <jlisee umd.edu> writes:
In article <ealh03$htp$1 digitaldaemon.com>, Sean Kelly <sean f4.ca> 
wrote:

 Joseph Lisee wrote:
 In article <e5l5v8$1g7j$1 digitaldaemon.com>,
  Tom S <h3r3tic remove.mat.uni.torun.pl> wrote:
 
 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.

/+ 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. +/

I vote for the assert(condition, "msg"), construct as well.

This feature was added a number of builds ago. Sean

That is what happens when I don't read the documentation close enough and not pay attention to message dates. It should also be noted that the in the Contract Programming page of the documentation it only mentions "assert(expression)". While It does link to the full documentation on the assert expression should that page also mention the option for a message? Sorry to clutter the mailing list. I will just go back to my attempt at wrapping C++ with doxygen + python. Yes I am aware of the D module for Swig, but I am going for something more elegant and this effort is a good C++, Python, and D programming exercise. -Joseph
Aug 01 2006
parent reply Kirk McDonald <kirklin.mcdonald gmail.com> writes:
Joseph Lisee wrote:
 In article <ealh03$htp$1 digitaldaemon.com>, Sean Kelly <sean f4.ca> 
 wrote:
 
 
Joseph Lisee wrote:

In article <e5l5v8$1g7j$1 digitaldaemon.com>,
 Tom S <h3r3tic remove.mat.uni.torun.pl> wrote:


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. +/

I vote for the assert(condition, "msg"), construct as well.

This feature was added a number of builds ago. Sean

That is what happens when I don't read the documentation close enough and not pay attention to message dates. It should also be noted that the in the Contract Programming page of the documentation it only mentions "assert(expression)". While It does link to the full documentation on the assert expression should that page also mention the option for a message? Sorry to clutter the mailing list. I will just go back to my attempt at wrapping C++ with doxygen + python. Yes I am aware of the D module for Swig, but I am going for something more elegant and this effort is a good C++, Python, and D programming exercise.

Are you aware of my Pyd library? It's a wrapper around the Python API, analogous to Boost::Python, but for D. It's probably not quite ready for serious use (for one thing, I haven't really documented it yet; for another, I haven't added Linux support yet, though it's going in Real Soon Now (tm)), but it might be worth taking a look at. So yeah, this is yet another unfinished, undocumented open-source project, but it is still capable of the following and more: [testdll.d] import pyd.pyd; import std.stdio; class Foo { int m_i; this() { m_i = 0; } this(int i) { m_i = i; } void foo() { writefln("i = ", m_i); } int i() { return m_i; } void i(int j) { m_i = j; } } void bar(int i) { writefln("You entered: ", i); } extern(C) export void inittestdll() { // Function wrapping def!(bar, "bar"); module_init("testdll"); // Class wrapping wrapped_class!(Foo, "Foo") f; // Constructor wrapping f.init!(tuple!(int)); // Member function wrapping f.def!(Foo.foo, "foo"); // Property wrapping f.prop!(Foo.i, "i"); finalize_class(f); } // EOF And in Python:
 import testdll
 testdll.bar(20)



 f = testdll.Foo(30)
 f.i



 f.i = 50
 f.foo()



It also comes with an extension to Python's distutils (David Rushby's CeleriD), to make building these extensions so much easier. Even if you don't use Pyd, the project has what I believe is the most complete version of the Python API header, which would probably be useful to you: http://dsource.org/projects/pyd/browser/trunk/infrastructure/python/headers/python.d -- Kirk McDonald Pyd: Wrapping Python with D http://dsource.org/projects/pyd/wiki
Aug 01 2006
parent reply Joseph Lisee <jlisee umd.edu> writes:
In article <eao805$2svv$1 digitaldaemon.com>,
 Kirk McDonald <kirklin.mcdonald gmail.com> wrote:


 Are you aware of my Pyd library? It's a wrapper around the Python API, 
 analogous to Boost::Python, but for D. It's probably not quite ready for 
 serious use (for one thing, I haven't really documented it yet; for 
 another, I haven't added Linux support yet, though it's going in Real 
 Soon Now (tm)), but it might be worth taking a look at.
 
 So yeah, this is yet another unfinished, undocumented open-source 
 project, but it is still capable of the following and more:
 
 [testdll.d]
 import pyd.pyd;
 import std.stdio;
 
 class Foo {
      int m_i;
      this() { m_i = 0; }
      this(int i) { m_i = i; }
 
      void foo() { writefln("i = ", m_i); }
      int i() { return m_i; }
      void i(int j) { m_i = j; }
 }
 
 void bar(int i) {
      writefln("You entered: ", i);
 }
 
 extern(C)
 export void inittestdll() {
      // Function wrapping
      def!(bar, "bar");
 
      module_init("testdll");
 
      // Class wrapping
      wrapped_class!(Foo, "Foo") f;
      // Constructor wrapping
      f.init!(tuple!(int));
      // Member function wrapping
      f.def!(Foo.foo, "foo");
      // Property wrapping
      f.prop!(Foo.i, "i");
      finalize_class(f);
 }
 // EOF
 
 And in Python:
 
  >>> import testdll
  >>> testdll.bar(20)
 You entered: 20
  >>> f = testdll.Foo(30)
  >>> f.i
 30
  >>> f.i = 50
  >>> f.foo()
 i = 50
 
 It also comes with an extension to Python's distutils (David Rushby's 
 CeleriD), to make building these extensions so much easier.
 
 Even if you don't use Pyd, the project has what I believe is the most 
 complete version of the Python API header, which would probably be 
 useful to you:
 http://dsource.org/projects/pyd/browser/trunk/infrastructure/python/headers/py
 thon.d

I have seen your library and I think it will be a great addition to D, what parts of linux support are missing? I don't think PyD will apply to my project. Let me get incredibly off topic and explain a little more. I am trying to make a program that generates wrappers for C++ programs so you can use them in D. My current plan is to process the XML output from Doxygen with Python and the ElementTree library. I will then generate a C++ file with a C interface to the class and D wrapper file for each class. Something similar to below: // C++ Code class MyClass { int m_num; public: MyClass(int num) { m_num = num; } int getNum() { return m_num; } }; // C Wrapper Code extern "C" { void* MyClass_new(int num) { return (void*)(new myClass(num)); } int MyClass_getNum(void* obj) { return ((myClass*)obj)->getNum(); } void MyClass_delete(void* obj) { delete (myClass*)obj; } } // D wrapper class extern (C) { void* MyClass_new(int num); int MyClass_getNum(void* obj); void MyClass_delete(void* obj); } class MyClass { private void* cppObj; this(int num) { cppObj = MyClass_new(num); } ~this() { MyClass_delete(cppObj); } int getNum() { return MyClass_getNum(cppObj); } } That is a very basic example and doesn't handle exception being thrown from the C++ code. I haven't start work on the generator yet. I am currently testing my ideas on the following issues: -properly handling the passing of D wrapped C++ classes to and from the C++ code. -using directors at the bottom of the inheritance tree to properly pass virtual function calls of to inherited D class -Throwing C++ and D exceptions through the interface that has C linkage. -Mapping of types from C++ to C to D. If this ever gets off the ground I am thinking of calling it WrapeD, the lack of two p's is intentional. I hope to have simpler interface file system than swig. Something looks more like SCons build files. -Joseph
Aug 01 2006
next sibling parent Kirk McDonald <kirklin.mcdonald gmail.com> writes:
Joseph Lisee wrote:
 I have seen your library and I think it will be a great addition to D, 
 what parts of linux support are missing?
 

Mostly I need to re-write CeleriD's DCompiler classes to add support for gdc. Building shared libraries with DMD on Linux doesn't work, but using gdc does. This is farily tedious (it basically means re-writing the entire dcompiler.py module), but I'm bashing away at it. -- Kirk McDonald Pyd: Wrapping Python with D http://dsource.org/projects/pyd/wiki
Aug 01 2006
prev sibling parent reply =?ISO-8859-1?Q?=22R=E9my_J=2E_A=2E_Mou=EBza=22?= writes:
I've done something close to what you discribe using Python ( C++ 
wrapping using the output of gccxml ). You can have a look at it on 
http://remy.moueza.free.fr. Gregor Richards has done better with BCD, 
available on dsource, only using D and gccxml. Swig also output xml, 
thus it is also possible to use it as an alternative to gccxml. I didn't 
know doxygen could output an xml view of its analysis.
Good luck.

 I don't think PyD will apply to my project.  Let me get incredibly off 
 topic and explain a little more. I am trying to make a program that 
 generates wrappers for C++ programs so you can use them in D.  My 
 current plan is to process the XML output from Doxygen with Python and 
 the ElementTree library.  I will then generate a C++ file with a C 
 interface to the class and D wrapper file for each class.  Something 
 similar to below:
 
 // C++ Code
 class MyClass {
    int m_num;
 public:
     MyClass(int num) {
         m_num = num;
     }
 
     int getNum() {
         return m_num;
     }
 };
 
 // C Wrapper Code
 extern "C"
 {
     void* MyClass_new(int num) {
         return (void*)(new myClass(num));
     }
 
     int MyClass_getNum(void* obj) {
         return ((myClass*)obj)->getNum();
     }
 
     void MyClass_delete(void* obj) {
         delete (myClass*)obj;
     }
 }
 
 // D wrapper class
 extern (C)
 {
     void* MyClass_new(int num);
     int MyClass_getNum(void* obj);
     void MyClass_delete(void* obj);
 }
 
 class MyClass {
     private void* cppObj;
 
     this(int num) {
         cppObj = MyClass_new(num);
     }
 
     ~this() {
         MyClass_delete(cppObj);
     }
 
     int getNum() {
         return MyClass_getNum(cppObj);
     }
 }
 
 That is a very basic example and doesn't handle exception being thrown 
 from the C++ code.  I haven't start work on the generator yet.  I am 
 currently testing my ideas on the following issues:
 
   -properly handling the passing of D wrapped C++ classes to and from 
 the C++ code.
   -using directors at the bottom of the inheritance tree to properly 
 pass virtual function calls of to inherited D class
   -Throwing C++ and D exceptions through the interface that has C 
 linkage.
   -Mapping of types from C++ to C to D.
 
 If this ever gets off the ground I am thinking of calling it WrapeD, the 
 lack of two p's is intentional.  I hope to have simpler interface file 
 system than swig.  Something looks more like SCons build files.
 
 -Joseph

Aug 02 2006
parent reply Joseph Lisee <jlisee umd.edu> writes:
In article <eapnnc$14sh$1 digitaldaemon.com>,
 "Rémy J. A. Mouëza" <ray.jay.ay.moueza do.not.spam.gmail.com> wrote:

 I've done something close to what you discribe using Python ( C++ 
 wrapping using the output of gccxml ). You can have a look at it on 
 http://remy.moueza.free.fr. Gregor Richards has done better with BCD, 
 available on dsource, only using D and gccxml. Swig also output xml, 
 thus it is also possible to use it as an alternative to gccxml. I didn't 
 know doxygen could output an xml view of its analysis.
 Good luck.

I looked at your project about a week ago but did not have gccxml installed at the time and all of the comments as to what works, and what didn't work are in French. I will give it a go and see what kind of code it produces. Could you translate the comments to French, or maybe just put the information on the website you provided above? -Joseph
Aug 02 2006
parent reply =?ISO-8859-1?Q?=22R=E9my_J=2E_A=2E_Mou=EBza=22?= writes:
Joseph Lisee a écrit :
 I looked at your project about a week ago but did not have gccxml 
 installed at the time and all of the comments as to what works, and what 
 didn't work are in French.  I will give it a go and see what kind of 
 code it produces.  
 
 Could you translate the comments to French, or maybe just put the 
 information on the website you provided above?
 
 -Joseph

Yes, I can. By the time I've written those comments they were kind of log of the progress I was doing. They just lists problems that happened and that I resolved and a few things to improve. They were not intended to be used as documentation. I haven't updated the site for a long time, I will first resolve my ftp access and ftp client problems first and update the site with a translated version of these log messages.
Aug 03 2006
parent =?ISO-8859-1?Q?=22R=E9my_J=2E_A=2E_Mou=EBza=22?= writes:
Rémy J. A. Mouëza a écrit :
 Joseph Lisee a écrit :
 I looked at your project about a week ago but did not have gccxml 
 installed at the time and all of the comments as to what works, and 
 what didn't work are in French.  I will give it a go and see what kind 
 of code it produces. 
 Could you translate the comments to French, or maybe just put the 
 information on the website you provided above?

 -Joseph

Yes, I can. By the time I've written those comments they were kind of log of the progress I was doing. They just lists problems that happened and that I resolved and a few things to improve. They were not intended to be used as documentation. I haven't updated the site for a long time, I will first resolve my ftp access and ftp client problems first and update the site with a translated version of these log messages.

As I had problems with the firewall of my university and ftp connection,I used my wiki (I had forgotten I set up one, and just started to use it). Translation of the french comments is available: http://remy.moueza.free.fr/wikini/wakka.php?wiki=DeeWrapperGenerator And I have written a few line on my feelings about that wrapper generator.
Aug 07 2006
prev sibling next sibling parent reply Sean Kelly <sean f4.ca> writes:
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
parent reply "Derek Parnell" <derek psych.ward> writes:
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.

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
next sibling parent BCS <BCS pathlink.com> writes:
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
prev sibling parent reply Sean Kelly <sean f4.ca> writes:
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.

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
May 31 2006
parent reply kris <foo bar.com> writes:
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?
May 31 2006
parent Derek Parnell <derek psych.ward> writes:
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
May 31 2006
prev sibling next sibling parent reply "Unknown W. Brackets" <unknown simplemachines.org> writes:
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?

May 31 2006
parent reply Derek Parnell <derek psych.ward> writes:
On Wed, 31 May 2006 21:38:04 -0700, Unknown W. Brackets wrote:

 Walter,
 
 My most common use for having this is simple...

Excellent reply and I'm now convinced too. As a heretical aside, with the almost released new version of Build, you can do something like the C-styled assert macro. You can define a macro replacement pattern such as ... regexp <:assert\s(.*)::(.*):> = if (!($1)) {writefln(`%%s:%%s`, `$1`, `$2`); assert(0);} and then write in your code ... <:assert result != 0::Bad result:> which will transform into ... if (!(result != 0)) {writefln(`%s:%s`, `result != 0`, `Bad result`); assert(0);} -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocracy!" 1/06/2006 3:48:31 PM
May 31 2006
parent reply kris <foo bar.com> writes:
Derek Parnell wrote:
 On Wed, 31 May 2006 21:38:04 -0700, Unknown W. Brackets wrote:
 
 
Walter,

My most common use for having this is simple...

Excellent reply and I'm now convinced too. As a heretical aside, with the almost released new version of Build, you can do something like the C-styled assert macro. You can define a macro replacement pattern such as ... regexp <:assert\s(.*)::(.*):> = if (!($1)) {writefln(`%%s:%%s`, `$1`, `$2`); assert(0);} and then write in your code ... <:assert result != 0::Bad result:> which will transform into ... if (!(result != 0)) {writefln(`%s:%s`, `result != 0`, `Bad result`); assert(0);}

I wish I could understand why this is needed in Build, Derek ... Build is truly great, at what it does well. Now it apparently allows one to intimately tie their code to Build, for all eternity, by extending the D language? Does this new stuff slow it down even a tiny bit? Sorry if this comes off a bit negative, but Build is just so good as it is. Still, it is your baby :)
May 31 2006
parent reply Derek Parnell <derek psych.ward> writes:
On Wed, 31 May 2006 23:12:42 -0700, kris wrote:

 I wish I could understand why this is needed in Build, Derek ... Build 
 is truly great, at what it does well. Now it apparently allows one to 
 intimately tie their code to Build, for all eternity, by extending the D 
 language? Does this new stuff slow it down even a tiny bit?
 
 Sorry if this comes off a bit negative, but Build is just so good as it 
 is. Still, it is your baby :)

Not at all! I love to hear real users' feedback. Rest assured though that from a performance point of view, you won't notice anything if you aren't using this facility, because it doesn't do text preprocessing on ".d" files. Instead you have to explicitly use ".mac" files which are transformed into ".d" files. However in the end, you are not forced into using the text processing stuff, just like you are not forced into using 'goto'. One reason for extending Build is so I can use it to build things other than D applications. But I've kept in mind the 'normal' case of using it with D so that is where the performance bias is. But there will now be a few milliseconds extra delay at start up time because I've replaced a lot of hard-coded strings with user-definable ones, which are cached when the program starts. ------ I just had a bit more of a go at an 'assert' macro and it can actually do this ... regexp assert\((.*),(.*)\); = if (!($1)) {writefln(`%%s:%%s`, `$1`, $2); assert(0);} used as ... assert(result != 0, "Bad result"); and comes out as ... if (!(result != 0)) {writefln(`%s:%s`, `result != 0`, "Bad result"); assert(0);} So Walter, if you want to stop this nasty abomination of source code abuse, please allow coder defined messages in the built-in assert statement ;-) -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocracy!" 1/06/2006 4:20:39 PM
May 31 2006
next sibling parent kris <foo bar.com> writes:
Derek Parnell wrote:
 Rest assured though that from a performance point of view, you won't notice
 anything if you aren't using this facility, because it doesn't do text
 preprocessing on ".d" files. Instead you have to explicitly use ".mac"
 files which are transformed into ".d" files.

Whew! Thanks :-D [snip]
 So Walter, if you want to stop this nasty abomination of source code abuse,
 please allow coder defined messages in the built-in assert statement ;-)

Right on!
May 31 2006
prev sibling next sibling parent Daniel Keep <daniel.keep.lists gmail.com> writes:
Derek Parnell wrote:
 On Wed, 31 May 2006 23:12:42 -0700, kris wrote:
 
 [snip]
 
 So Walter, if you want to stop this nasty abomination of source code abuse,
 please allow coder defined messages in the built-in assert statement ;-)
 

"Alright, this is a hold up! No body move! "Now, listen up; in this bag here I 'ave a three megaton regex macro pre-processor, and I ain't afraids to use it! If youse don't comply wit my demands, you'll leave me no choice but to butcher your pristine littl' language just like wot happened to C! "First, make it so that we can prints us some bloody context from asserts! "Second, we wants to bloody know where in a file the bloody exceptions are commin' from, and no not everyone can figure out how to use bloody WinDbg! "Thirds, I wants me a bloody sandwich!" "This is the police! We have the newsgroups surrounded; come out with your hands up, and the new version of build clearly visible or we'll shoot you!" "Oh 'ell." -------------------- On a more serious note, this looks *evil*. In a, y'know, really handy kind of a way. But what I've always wanted is something similar to what Nemerle has. For example, this is how the 'for' structure is defined in Nemerle: # macro for (init, cond, change, body) # { # <[ # $init; # def loop () : void { # if ($cond) { $body; $change; loop() } # else () # }; # loop () # ]> # } Everything inside the <[ ... ]> "quotes" is treated as the substitute syntax tree. The nice thing about this over plain old text substitution is that it's all typesafe: it only allows you to substitute complete, valid syntax trees. Aside from that, you can also directly create and modify the AST (since the "macro" is really just a function run by the compiler; the funky <[ ... ]> quotes are just syntactic sugar). Whatever you return from the function is what replaces the macro use in the source file. Anyway, just my AU$0.02. -- Daniel -- Unlike Knuth, I have neither proven or tried the above; it may not even make sense. v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
Jun 01 2006
prev sibling parent reply pragma <pragma_member pathlink.com> writes:
In article <2dpe83lsz5rb.v7hpd58hsxeu.dlg 40tude.net>, Derek Parnell says...
One reason for extending Build is so I can use it to build things other
than D applications. But I've kept in mind the 'normal' case of using it
with D so that is where the performance bias is.

Its interesting that you mention this. I recently drafted a parser-frontend generator that generates .d code as output; it works a treat, but I'm presently having to go through multiple build steps. So, would "things other than D applications" happen to cover preprocessors other than just .mac file handling? ;)
So Walter, if you want to stop this nasty abomination of source code abuse,
please allow coder defined messages in the built-in assert statement ;-)

Nice. In a more serious, and on-topic note, I too believe that assert() could stand some expansion to allow for more succinct error reporting. It all comes down to the matter of reporting "how and why" something breaks rather than just "where". As a preface, I for one do not use an IDE when developing my software. D seems to do pretty well for me without it, although I'm still longing for out-of-the-box stack tracing. Anyway, so I run some code that trips on an assert, and it coughs up "foobar.d(42)" as where I need to look. The assert has done its job, as I go to line #42 and go hunting for the reason behind why it tripped up. As I'm basically flying blind (no watch window and no stack trace), my next step is almost always: add a writefln() before the assert to get some more information as to how this happened. Meshing those two steps seems like an obvious choice to me. Another way to look at it is in the use of static assert(). With the compile-time regexp processor(s) out there, they halt on static assert() and then cough up some rudimentary explaination as to *why* using pragma(msg). I wouldn't even consider either implementation usable without the msg/assert idiom, so I don't really use them apart from each other. In fact, I'll argue that its impossible to meaningfully extend the compiler/D-grammar through templates without using the two together; the library user just wouldn't have a clue otherwise. To sum up: I honestly feel that the two capabilities, assert() and writefln(), should be merged into an extended assert() statment, for the sake of encouraging better coding and library use. - EricAnderton at yahoo
Jun 01 2006
next sibling parent reply Oskar Linde <oskar.lindeREM OVEgmail.com> writes:
pragma wrote:
 In a more serious, and on-topic note, I too believe that assert() could stand
 some expansion to allow for more succinct error reporting.  It all comes down
to
 the matter of reporting "how and why" something breaks rather than just
"where".
 
 As a preface, I for one do not use an IDE when developing my software.  D seems
 to do pretty well for me without it, although I'm still longing for
 out-of-the-box stack tracing.
 
 Anyway, so I run some code that trips on an assert, and it coughs up
 "foobar.d(42)" as where I need to look.  The assert has done its job, as I go
to
 line #42 and go hunting for the reason behind why it tripped up.  As I'm
 basically flying blind (no watch window and no stack trace), my next step is
 almost always: add a writefln() before the assert to get some more information
 as to how this happened.  Meshing those two steps seems like an obvious choice
 to me.

What I do is redefine the implementation of assert to do: *(cast(int *)0) = 0; That way, I get a segmentation fault and a core dump that the debugger (gdb) is able to use to present me with a back trace and (all) local variables available for inspection. This is immensely more useful than letting assert throw an exception, which means losing all state and stack trace information. /Oskar
Jun 01 2006
parent reply kris <foo bar.com> writes:
Oskar Linde wrote:
 pragma wrote:
 Anyway, so I run some code that trips on an assert, and it coughs up
 "foobar.d(42)" as where I need to look.  The assert has done its job, 
 as I go to
 line #42 and go hunting for the reason behind why it tripped up.  As I'm
 basically flying blind (no watch window and no stack trace), my next 
 step is
 almost always: add a writefln() before the assert to get some more 
 information
 as to how this happened.  Meshing those two steps seems like an 
 obvious choice
 to me.

What I do is redefine the implementation of assert to do: *(cast(int *)0) = 0; That way, I get a segmentation fault and a core dump that the debugger (gdb) is able to use to present me with a back trace and (all) local variables available for inspection. This is immensely more useful than letting assert throw an exception, which means losing all state and stack trace information. /Oskar

And therein lies the key: what everyone is asking for is a means to capture additional state with the assert() Ideally, all code-testing would be performed within the comforting arms of a debugger. But it doesn't happen that way and, due to Murphy's law, the one and only time your code trips up is when it's not in the debugger. That's when you need additional state to help track things down; especially with those "non repeatable" bugs. Having said that, a very large part of the valuable state is the stack-trace ~ "how did we get here" can be just as important as some key variable. Often more so. Thus, I tend to look at assert as the bare minimum of tools; scraping the barrel, if you will. That goes to show how poor the runtime diagnostic support really is in D at this time ~ we're actually better off with printf() than most anythng else :) Thus when all is said and done, having support for a stack-trace seems far more valuable than the 'convenience' of an assert message. Although in the absence of the former, it's easy to see why assert() gets so much attention. Finally, I suspect adding printf formatting to assert() would be binding complexity at a delicate level; partly because the formatting might try to allocate memory? Let's get stack-tracing supported, instead of depending upon the marginally useful assert() statement :D - Kris
Jun 01 2006
parent reply James Dunne <james.jdunne gmail.com> writes:
kris wrote:
 Oskar Linde wrote:
 
 pragma wrote:

 Anyway, so I run some code that trips on an assert, and it coughs up
 "foobar.d(42)" as where I need to look.  The assert has done its job, 
 as I go to
 line #42 and go hunting for the reason behind why it tripped up.  As I'm
 basically flying blind (no watch window and no stack trace), my next 
 step is
 almost always: add a writefln() before the assert to get some more 
 information
 as to how this happened.  Meshing those two steps seems like an 
 obvious choice
 to me.

What I do is redefine the implementation of assert to do: *(cast(int *)0) = 0; That way, I get a segmentation fault and a core dump that the debugger (gdb) is able to use to present me with a back trace and (all) local variables available for inspection. This is immensely more useful than letting assert throw an exception, which means losing all state and stack trace information. /Oskar

And therein lies the key: what everyone is asking for is a means to capture additional state with the assert() Ideally, all code-testing would be performed within the comforting arms of a debugger. But it doesn't happen that way and, due to Murphy's law, the one and only time your code trips up is when it's not in the debugger. That's when you need additional state to help track things down; especially with those "non repeatable" bugs. Having said that, a very large part of the valuable state is the stack-trace ~ "how did we get here" can be just as important as some key variable. Often more so. Thus, I tend to look at assert as the bare minimum of tools; scraping the barrel, if you will. That goes to show how poor the runtime diagnostic support really is in D at this time ~ we're actually better off with printf() than most anythng else :) Thus when all is said and done, having support for a stack-trace seems far more valuable than the 'convenience' of an assert message. Although in the absence of the former, it's easy to see why assert() gets so much attention. Finally, I suspect adding printf formatting to assert() would be binding complexity at a delicate level; partly because the formatting might try to allocate memory? Let's get stack-tracing supported, instead of depending upon the marginally useful assert() statement :D - Kris

I'm sorry but I really have to insert my skepticism here about stack traces. Upon first glance it sounds like a wonderful idea, until you get to where Java is at. Literally hundreds of lines of stack traces dumped into log files to wade thru, most of them completely useless because: THEY DON'T CONTAIN STATE!!! Sure they have the call-stack state so you can see where the function calls came from but there are no local variables, no function parameter values, no class/struct dumps; basically nothing useful for anything more complex than the simplest case of a deterministic function call, and even then it's not too terribly useful. While I agree that it is better than nothing, we can still do better. An entire run-time debugging framework is what we really want to shoot for. Exception logging, tracing, dumping of object contents, reading local variables, reading function parameters, etc. This probably requires the help of a compile-time reflection system (where certain properties of objects are translated by the compiler into literal expressions). Run-time reflection isn't really necessary. -- Regards, James Dunne
Jun 01 2006
next sibling parent kris <foo bar.com> writes:
James Dunne wrote:
 I'm sorry but I really have to insert my skepticism here about stack 
 traces.
 
 Upon first glance it sounds like a wonderful idea, until you get to 
 where Java is at.  Literally hundreds of lines of stack traces dumped 
 into log files to wade thru, most of them completely useless because: 
 THEY DON'T CONTAIN STATE!!!
 
 Sure they have the call-stack state so you can see where the function 
 calls came from but there are no local variables, no function parameter 
 values, no class/struct dumps; basically nothing useful for anything 
 more complex than the simplest case of a deterministic function call, 
 and even then it's not too terribly useful.
 
 While I agree that it is better than nothing, we can still do better. An 
 entire run-time debugging framework is what we really want to shoot 
 for.  Exception logging, tracing, dumping of object contents, reading 
 local variables, reading function parameters, etc.  This probably 
 requires the help of a compile-time reflection system (where certain 
 properties of objects are translated by the compiler into literal 
 expressions).  Run-time reflection isn't really necessary.

Fair enough; I find it vaguely interesting that there's been a log4j clone publicly available for 25 months now, yet I'm perhaps the only one who uses it -- lol -- what does that tell you? If anything? :-D
Jun 01 2006
prev sibling next sibling parent Don Clugston <dac nospam.com.au> writes:
James Dunne wrote:
 kris wrote:
 Oskar Linde wrote:

 pragma wrote:

 Anyway, so I run some code that trips on an assert, and it coughs up
 "foobar.d(42)" as where I need to look.  The assert has done its 
 job, as I go to
 line #42 and go hunting for the reason behind why it tripped up.  As 
 I'm
 basically flying blind (no watch window and no stack trace), my next 
 step is
 almost always: add a writefln() before the assert to get some more 
 information
 as to how this happened.  Meshing those two steps seems like an 
 obvious choice
 to me.

What I do is redefine the implementation of assert to do: *(cast(int *)0) = 0; That way, I get a segmentation fault and a core dump that the debugger (gdb) is able to use to present me with a back trace and (all) local variables available for inspection. This is immensely more useful than letting assert throw an exception, which means losing all state and stack trace information. /Oskar

And therein lies the key: what everyone is asking for is a means to capture additional state with the assert() Ideally, all code-testing would be performed within the comforting arms of a debugger. But it doesn't happen that way and, due to Murphy's law, the one and only time your code trips up is when it's not in the debugger. That's when you need additional state to help track things down; especially with those "non repeatable" bugs. Having said that, a very large part of the valuable state is the stack-trace ~ "how did we get here" can be just as important as some key variable. Often more so. Thus, I tend to look at assert as the bare minimum of tools; scraping the barrel, if you will. That goes to show how poor the runtime diagnostic support really is in D at this time ~ we're actually better off with printf() than most anythng else :) Thus when all is said and done, having support for a stack-trace seems far more valuable than the 'convenience' of an assert message. Although in the absence of the former, it's easy to see why assert() gets so much attention. Finally, I suspect adding printf formatting to assert() would be binding complexity at a delicate level; partly because the formatting might try to allocate memory? Let's get stack-tracing supported, instead of depending upon the marginally useful assert() statement :D - Kris

I'm sorry but I really have to insert my skepticism here about stack traces. Upon first glance it sounds like a wonderful idea, until you get to where Java is at. Literally hundreds of lines of stack traces dumped into log files to wade thru, most of them completely useless because: THEY DON'T CONTAIN STATE!!!

 Sure they have the call-stack state so you can see where the function 
 calls came from but there are no local variables, no function parameter 
 values, no class/struct dumps; basically nothing useful for anything 
 more complex than the simplest case of a deterministic function call, 
 and even then it's not too terribly useful.

 While I agree that it is better than nothing, we can still do better. An 
 entire run-time debugging framework is what we really want to shoot 
 for.  Exception logging, tracing, dumping of object contents, reading 
 local variables, reading function parameters, etc.  This probably 
 requires the help of a compile-time reflection system (where certain 
 properties of objects are translated by the compiler into literal 
 expressions).  Run-time reflection isn't really necessary.

I have to disagree with this. A stack trace does give you the most important piece of state information: the value of function pointers and delegates that are called. Personally, I don't think I've ever learnt much from a debugger other than seeing the call stack; it gives a list of all the places to look at for bugs (and the places to put more asserts into!). It covers >90% of the use cases.
Jun 02 2006
prev sibling parent BCS <BCS_member pathlink.com> writes:
In article <e5odr1$2mis$1 digitaldaemon.com>, James Dunne says...

I'm sorry but I really have to insert my skepticism here about stack traces.

Upon first glance it sounds like a wonderful idea, until you get to 
where Java is at.  Literally hundreds of lines of stack traces dumped 
into log files to wade thru, most of them completely useless because: 
THEY DON'T CONTAIN STATE!!!

A lot of state can be gained with scope(failure) statements. I have a program where (as an experiment) every function is prefaced with: # scope(failure) writef("StackTrace "__FILE__":"~itoa!(__LINE__)~\n); If I needed some state a few more scope(failure) line would do this quite nicely. I will grant, just an automated stack trace might not be to useful, but throwing in parameter values, called from info (line#) and the like would give you a good idea where things stand. OTOH if I was trying to run an automated bug tracking system that gets reports from crashed sessions, a stack trace would be exactly where I would start.
Sure they have the call-stack state so you can see where the function 
calls came from but there are no local variables, no function parameter 
values, no class/struct dumps; basically nothing useful for anything 
more complex than the simplest case of a deterministic function call, 
and even then it's not too terribly useful.

While I agree that it is better than nothing, we can still do better. 
An entire run-time debugging framework is what we really want to shoot 
for.  Exception logging, tracing, dumping of object contents, reading 
local variables, reading function parameters, etc.  This probably 
requires the help of a compile-time reflection system (where certain 
properties of objects are translated by the compiler into literal 
expressions).  Run-time reflection isn't really necessary.

-- 
Regards,
James Dunne

Jun 02 2006
prev sibling next sibling parent reply Sean Kelly <sean f4.ca> writes:
pragma wrote:
 
 Another way to look at it is in the use of static assert().  With the
 compile-time regexp processor(s) out there, they halt on static assert() and
 then cough up some rudimentary explaination as to *why* using pragma(msg).  I
 wouldn't even consider either implementation usable without the msg/assert
 idiom, so I don't really use them apart from each other.  In fact, I'll argue
 that its impossible to meaningfully extend the compiler/D-grammar through
 templates without using the two together; the library user just wouldn't have a
 clue otherwise.

Good point. If this change were made, would it apply to static assert as well? It would certainly be nice. Sean
Jun 01 2006
parent reply Don Clugston <dac nospam.com.au> writes:
Sean Kelly wrote:
 pragma wrote:
 Another way to look at it is in the use of static assert().  With the
 compile-time regexp processor(s) out there, they halt on static 
 assert() and
 then cough up some rudimentary explaination as to *why* using 
 pragma(msg).  I
 wouldn't even consider either implementation usable without the 
 msg/assert
 idiom, so I don't really use them apart from each other.  In fact, 
 I'll argue
 that its impossible to meaningfully extend the compiler/D-grammar through
 templates without using the two together; the library user just 
 wouldn't have a
 clue otherwise.


[ie, just like C++!] That's my experience too. It's possible to have excellent usability now that we have sudden-death static asserts.
 Good point.  If this change were made, would it apply to static assert 
 as well?  It would certainly be nice.

The case for a message in static assert is very much stronger than for assert. (a) You don't have a debugger -- there's no way of finding what's going on apart from seeing the assert. (b) The message is always for the programmer, not the end user. (c) Established practice is to use pragma(msg) with static assert(0). My code is littered with: static if (!cond) { pragma(msg, "xxx"); static assert(0); } It would be so much cleaner to replace this with static assert(cond, "xxx"); (and it would accentuate the superiority of D templates over C++).
Jun 02 2006
parent "Unknown W. Brackets" <unknown simplemachines.org> writes:
I use:

static assert ("Message", 0);

Which gives a message similar to:

static assert  ("Message" , 0) is false

-[Unknown]


 My code is littered with:
 
 static if (!cond) {
   pragma(msg, "xxx");
   static assert(0);
 }

Jun 02 2006
prev sibling parent Thomas Kuehne <thomas-dloop kuehne.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

pragma schrieb am 2006-06-01:
 To sum up: I honestly feel that the two capabilities, assert() and writefln(),
 should be merged into an extended assert() statment, for the sake of
encouraging
 better coding and library use.

That's easy: # import std.stdio; # import std.stdarg; # # bool assertln(...){ # writefx(stdout, _arguments, _argptr, 1); # return false; # } # # # // ... # assert(a == b || assertln("%s != %s", a, b)); # // ... # Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFEf1ix3w+/yD4P9tIRAjo6AJ9jH5cEKVNBjPCDAfi/MO14xqSumACfQMem fhE84xqWoqTYtOg895pDA58= =0sAG -----END PGP SIGNATURE-----
Jun 01 2006
prev sibling next sibling parent Brad Roberts <braddr puremagic.com> writes:
On Wed, 31 May 2006, Brad Roberts wrote:

 On Wed, 31 May 2006, 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?

I've reapplied the referenced patch to dmd/gdc and it works when used properly. However, exactly like it was before, it's got a number of bugs when used improperly. I need to learn more about dmd and gdc both to fix the thing to be robust enough to actually merge in.

The current patch: http://www.puremagic.com/~braddr/d/assert-optional-message-0.2-gdc-0.18.diff http://www.puremagic.com/~braddr/d/assert-test.d There's a couple issues with the code as it stands: 1) most of the code is in the gdc layer, meaning that to incorporate with dmd walter will have to do some work. This can't be helped, probably. 2) rather than introduce a new _d_assert_with_message() api to the runtime, I've chosen to default to "" if no assert message is specified. 3) the runtime code in phobos/std/assertinternal.d recognizes "" as 'no message' 4) assert(condition, non-string-constant) produces an ICE in the gdc glue layer 5) assert(condition, non-string-expression) produces an odd error message: Integer constant expression expected instead of (test7func)() I'm continuing to work on 4 and 5. For now, I'm leaving 1-3 as is unless there's some outcry that guilts me into working on them more. Later, Brad
May 31 2006
prev sibling next sibling parent Brad Roberts <braddr puremagic.com> writes:
On Thu, 1 Jun 2006, James Dunne wrote:

 I'm sorry but I really have to insert my skepticism here about stack traces.
 
 Upon first glance it sounds like a wonderful idea, until you get to where Java
 is at.  Literally hundreds of lines of stack traces dumped into log files to
 wade thru, most of them completely useless because: THEY DON'T CONTAIN
 STATE!!!
 
 Sure they have the call-stack state so you can see where the function calls
 came from but there are no local variables, no function parameter values, no
 class/struct dumps; basically nothing useful for anything more complex than
 the simplest case of a deterministic function call, and even then it's not too
 terribly useful.
 
 While I agree that it is better than nothing, we can still do better. An
 entire run-time debugging framework is what we really want to shoot for.
 Exception logging, tracing, dumping of object contents, reading local
 variables, reading function parameters, etc.  This probably requires the help
 of a compile-time reflection system (where certain properties of objects are
 translated by the compiler into literal expressions).  Run-time reflection
 isn't really necessary.
 
 -- 
 Regards,
 James Dunne

At that point, you really just want the core file. Given the program image and the core, you can do all of the above.
Jun 01 2006
prev sibling parent Brad Roberts <braddr puremagic.com> writes:
On Mon, 31 Jul 2006, Joseph Lisee wrote:

 In article <e5l5v8$1g7j$1 digitaldaemon.com>,
  Tom S <h3r3tic remove.mat.uni.torun.pl> wrote:
 
 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. +/

I vote for the assert(condition, "msg"), construct as well. CXX Test and JUnit have spoiled me. You can't even do assert(1 == 0 && "The laws of math have been changed"), which is trick I use in the C++ all the time. Is having a message with the assert going to hurt anything? -Joseph Lisee

Um.. you're voting for a feature that was added several releases ago. Later, Brad
Jul 31 2006