www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - extending assert

reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Is there any possibility to extend the "assert" ?

I can think of two really useful extensions...
1) Allow for the programmer to attach an explanation
2) Display the actual assert statement, like C does


Currently a lot of the D code simply uses "assert(0);"
Besides that I would rather see "assert(false);" myself
it really doesn't give more than a source line to go on ?

Like the ever popular:
 version (Windows) private import std.c.windows.windows;
 version (linux) private import std.c.linux.linux;
 else static assert(0); // unsupported platform

Wouldn't something like: "error("unsupported platform"); be better and more readily apparent when getting the Error ? Ditto, when getting an exception like "AssertError Failure format(730)", wouldn't I be helped by seeing something like:
 assertion (s == "1.67 -0X1.47AE147AE147BP+0 nan") failed

Since all assertions are stripped with -release anyway, there is not much fear of the code leaking out in the final builds ? (and, yes, the debugger does show me the source line directly) Or am I missing something here ? --anders
Feb 05 2005
next sibling parent reply "Unknown W. Brackets" <unknown simplemachines.org> writes:
I think this is very important for them to be really usable.  Yes, you 
can go check the line - you can always check the line, right?  Err, wrong.

The software I primarily write is open source (no, i didn't capatialize 
it, please don't pick hairs.)  There are, among other things, custom 
patches made by third parties readily available to apply to the source 
code.  An assert on line 730 would mean absolutely ziltch to me in many 
cases, because their line 730 could be 10, 20, even 100 lines away from 
my line of the same number.

Of course, I guess what I want, then, is an exception.  Except that 
gives me less information - no file/line information at all - just the 
error.  And I can't do something tricksy like this:

throw new ReallyCoolException("This shouldn't happen!", __FILE__, __LINE__);

Because __FILE__ and __LINE__ simply don't exist.  So I *am* supposed to 
use assert, then, right?  Why can't I have my message?

-[Unknown]

 1) Allow for the programmer to attach an explanation

Feb 05 2005
next sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Unknown W. Brackets wrote:

 The software I primarily write is open source (no, i didn't capatialize 
 it, please don't pick hairs.)  There are, among other things, custom 
 patches made by third parties readily available to apply to the source 
 code.  An assert on line 730 would mean absolutely ziltch to me in many 
 cases, because their line 730 could be 10, 20, even 100 lines away from 
 my line of the same number.

Most of the GDC "standard" modules are offset, just for that reason. (They're still all available in /opt/gdc/include/d here, but anyway) --anders PS. I normally just mean Open Source as "according to OSI", just like Free Software is as in "according to GNU"...
Feb 05 2005
parent "Unknown W. Brackets" <unknown simplemachines.org> writes:
As do I - the difference is, when I say "open source" (sans capitals) I 
mean that the source is available, you're allowed to change it, etc.  I 
don't mean OSI.  The software I write is not Open Source/Free because 
you cannot redistribute it - you can only redistribute patches (and this 
is almost allowed in the OSI definition, although it says compiled forms 
must still be redistributable.)

Anyway, yes, without looking I'm guessing that's exactly what I mean 
(about the line numbers.)

-[Unknown]

 PS. I normally just mean Open Source as "according to OSI",
     just like Free Software is as in "according to GNU"...

Feb 05 2005
prev sibling parent "Matthew" <admin stlsoft.dot.dot.dot.dot.org> writes:
 Of course, I guess what I want, then, is an exception.  Except that 
 gives me less information - no file/line information at all - just the 
 error.  And I can't do something tricksy like this:

 throw new ReallyCoolException("This shouldn't happen!", __FILE__, 
 __LINE__);

 Because __FILE__ and __LINE__ simply don't exist.  So I *am* supposed 
 to use assert, then, right?  Why can't I have my message?

 -[Unknown]

 1) Allow for the programmer to attach an explanation


There are three important issues here: 1. We should have access to compiler intrinsic symbols for file, line, class, function, module, date, time, compiler version, and probably several more I've not thought of. I know this was requested a long time ago, but I don't recollect the results of the debate. It's clear to me that some are absolutely necessary, and most would be useful, and I cannot think of a single reason why we can't have them. Walter, may we have a timely feedback on this? 2. We need the exception hierarchy refactored, and unrecoverable exceptions properly defined. A long while back I said I'd do a study of D's exception hierarchy, and I believe Ben and/or Sean also had the same intention. Pressure of work has thus far prevented me from completing the two page doc I got so far with, but as I now turn my attention more and more D-ward - for writing DPD - it is very unlikely that I won't also complete this work, unless someone else has or will do so within the next 4-6 weeks. 3. As discussed recently, in regards to the utility of having CP in released programs, we need 3a. the facility to have CP in released builds 3b. a separation, and clear definition, of the difference between a development/debug-time assert and a CP clause. I don't know whether this is going to spark a religious argument, but in my experience (and my opinion) it is useful to have some CP stuff in both debug and release mode, and stuff that's in debug only. Currently, D has only assert, which does not allow us to make this separation. I think we need more direct support The upshot of all these things, in respect of the OP, is that we should have something like the following: <not sure what it's root is> - UnrecoverableException / Error - ContractViolationException / Error - PreconditionViolationException / Error - PostconditionViolationException / Error - InvariantViolationException / Error - AssertionException / Error (- assumes that we have bifurcated assert()) Points: - UnrecoverableException would be an abstract class. - Anything derived from UnrecoverableException would have provided, by the language/compiler, the module(+class)+file+line of its _throw site_. Naturally, we'd want to be able to override the defaults, to facilitate rethrowing or whatever, so that's going to take some extra thinking about (given that we don't have a pre-processor, inlining is done differently than in C++). - unrecoverable exceptions (Errors; remember, let me play fast and loose here, since it's off the point) can be caught, but either have to be rethrown, or something else derived from the root unrecoverable exception, or, if no throw is included in the catch, the caught exception is automatically rethrown. [Note: these might be Errors. Something we need to sort out once someone, maybe me, has done the necessary exception hierarchy analysis/review.] Now, I assume that all of the foregoing is uncontentious (except maybe to Walter <g>), _except_ for the notion of the irrecoverability. I'd ask that, if anyone wants to chew on that particular wasp, that they start a new topic, so we can keep the rest of this very important issue - intrinsics + exception hierarchy + CP in release builds - in a relatively tight debate. Cheers Matthew
Feb 06 2005
prev sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Earlier, I wrote:

 Is there any possibility to extend the "assert" ?
 
 I can think of two really useful extensions...
 1) Allow for the programmer to attach an explanation
 2) Display the actual assert statement, like C does

As usual, this had been beaten to death here already... (some of you might recall me asking for "boolean" too) Walter wrote:
 Asserts are only for debugging purposes by the programmer who wrote the
 code, and the first thing the programmer will do is bring up the
 corresponding file/line in the editor. Presumably there will be some comment
 there explaining it. I don't see how adding a redundant string in the assert
 message itself adds value to this.

So I guess that "answers" that then. Like before, I was looking at Java: http://java.sun.com/j2se/1.4.2/docs/guide/lang/assert.html (JDK 1.4.2+) I thought something like: static assert(false; "Unsupported platform") or: assert(x > 10; format("%d is too small", x)) could have been useful? But I guess the debugger and the source code will do meanwhile, for D... (and it's not like I *want* the "let's leave all code in" that Java has) But having _file and _line variables could come in handy, none the less. Perhaps even _class and _function, like some extensions have added... --anders PS. Here's it how it looks in Java, by the way: (turning assertions on is done at *runtime*) test.java:
 public class test
 {
   public static void main(String[] args)
   {
     assert false;
   }
 }

# jikes -source 1.4 test.java # java test # java -ea test Exception in thread "main" java.lang.AssertionError at test.main(test.java:5)
 public class test
 {
   public static void main(String[] args)
   {
     assert false : "shucks";
   }
 }

# java -ea test Exception in thread "main" java.lang.AssertionError: shucks at test.main(test.java:5)
Feb 07 2005
parent reply marko <tm030127d galeb.etf.bg.ac.yu> writes:
How about this?

syntax: "assert" BoolExpr {("," | "&&") BoolExpr} [":" StringExpr] ";"
A|B matches A or B
{A} matches zero or more A
[A] matches zero or one A

There is no need for "(" and ")" around expressions.
AssertionException should contain source code of boolean expression that  
evaluated to false.
[assert A, B && C: E;] and [assert A, B, C: E;] should be treated
like [assert A: E; assert B: E; assert C: E;] when throwing exceptions

for example:
A is true
B is false
assert A, B && C;
Exception should contain only code for expression B, not complete B && C  
expression.

This is backward compatible with current assert.
Feb 07 2005
parent =?ISO-8859-15?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
marko wrote:

 How about this?
 
 syntax: "assert" BoolExpr {("," | "&&") BoolExpr} [":" StringExpr] ";"

It's OK, though different (in fact it looks identical to what Java has) But Walter doesn't like either booleans or assert messages, so it's out. And since there are no macros, there's no __FILE__ or __LINE__ either. So that leaves the C assertions we all growned to ... well, "stand" ? assert(0); // because I felt like it Just that NDEBUG is called -release, these days. And throws, not prints. --anders PS. I think I'll just fire up the good old extern(C) void Debugger();
Feb 08 2005