August 16, 2005
On Tue, 16 Aug 2005 04:03:59 +0000 (UTC), AJG wrote:

> Hi Derek,
> 
>>>Before anything, are the following three things clearly defined
>>> anywhere?
>>
>>Yes. In the documentation for the DMD compiler and the documentation for conditional compilation.
> 
> Well, I must be reading something wrong, cause...
> 
> ~test.d:
> # void main() {
> #     printf("Before\n");
> #     assert(false);
> #     printf("After\n");
> # }
> 
>>> A) -debug
>>-debug
>>compile in debug code
>>-debug=level
>>compile in debug code <= level
>>-debug=ident
>>compile in debug code identified by ident
> 
> This is fine. Debug seems to work properly.
> 
> Output:
> # Before
> # Error: AssertError Failure test.d(3)

>>> B) -release
>>-release
>>compile release version, which means not generating code for contracts and
>>asserts
>
>Not quite...
>
>Output:
># Before
># Segmentation Fault

According to the documentation (see 'Expressions')...
"
The expression assert(0) is a special case; it signifies that it is
unreachable code. Either AssertError is thrown at runtime if it is
reachable, or a HLT instruction is executed. The optimization and code
generation phases of compilation may assume that it is unreachable code.
"

What the docs do not make clear is that this special case assert is not totally removed by "-release" switch. Maybe it should ... maybe not? I don't know. However I do know that if you place a more typical assert there then the -release switch does remove it.


[snip]

> 
>>> It would make more sense to do the following:
>>> 
>>> # void Foo(int a) in {
>>> #     assert(a == 42); // Stays there forever.
>>Why? What useful information would this give to the end user?
> 
> It's _not_ about the user. It's about basic function safety.

I must disagree here - it *is* about the user. Why are we writing programs
if they are not meant to be used? We, as developers, must help the user by
delivering correct algorithms (our logic) using the correct information
(data from user). Function safety must check for at least two areas of
concern:
  a) the algorithm is correct;
  b) the data it is working with is correct.

Given (and I repeat, *given*) the current implementation of assert, which only gives file and line number info, how is that useful to an end-user? Sure its useful stuff to the development team, but how does it really make end-users feel warm and fuzzy?

The current assert implementation is designed to help developers detect *logic* problems. It is not designed to help us detect *data* problems. Sure it uses data to test, but the data is expected to come from the results of your logic, not stuff that is supplied by a user.

I'm not saying that this is how the world ought ot operate, just that this is how D operates. I'm not saying that Walter has got it right or wrong, just was exists in D. So starting from that position, do not use asserts to validate function arguments, instead use assert to validate function results.

> Why have a section
> called "in," where you are supposed to check for pre-conditions, when that
> section is effectively _useless_ in real code? This is a bad design decision,
> IMHO.

I agree that the way in{} is implemented makes it useless in all but the rarest of situations. I can't think of any reason to use it the way it currently is.

> Asserts are a simple and elegant way to prevent bizarre and potentially catastrophic behaviour that you don't expect to happen in real code, but just _might_.

But not D asserts(). May be you are right about the assert() as implemented in other languages. The basic premise of the assert concept is that it tests data and aborts the program if the test fails. The question that we are now dealing with is where does that data come from? If it comes from function arguments, then the D assert is useless code.

>When debugging, they are useful tools to the programmer. But they are
> doubly useful: In real code, they are last-resort, emergency guards.

This is a matter of opinion, because there are ways to validate data other than using the assert construct.

> Well, you say, throw an exception. You want me to instead throw an exception every time I have an assert? The sheer verbosity will kill you. For every:
> 
> assert(c);
> 
> You must use:
> 
> if (!c) throw new Exception("Error: AssertError Failure ajg.module.d(13)");
>
> Look at that monster. If you pepper your code with Exceptions where regular asserts would have sufficed, you are looking at some serious code bloat. Just like const, the meaning is lost in all that pomposity and syntax. Assert, on the other hand is concise and elegant. Therefore, I use asserts a lot, because I would want my code to be bulletproof.

In that case, ship an edition of your application that was not compiled with "-release". The choice is yours. No one is forcing you to use "-release".

> Moreover, there are even more disadvantages:
> 
> 1) It's a heck of a lot more work. You are less likely to do it.
> 2) You lose automatic module/line-number indications.
> 3) It's a more complex construct.
> 4) Thus, you lose the immediate, quick, straight-forward meaning. An assert is a
> simple guard. You see it an you know that condition must never happen.
> 
> OTOH, an exception is a much more powerful error-handling facility. When I put an assert, I don't want to handle an error, I want execution to come to a screeching halt lest the situation get even worse.

 assert(0)  ???

> Well, use a _function_ that throws an exception, you say. I suppose that's what your "Abend" function does, right? First off, still quite verbose:
> 
> # // Assuming this:
> # void assert2(int c, string m) {
> #     if (!c) throw new Exception("Error: AssertError Failure " ~ m);
> # }
> 
> assert(c);
> vs.
> assert2(c, "ajg.module.d(13)");
> 
> Even more problems:
> 
> 1) It's a lot more work. Harder to maintain.
> 2) Still no automatic module/line-number.
> 3) Even worse, now the exception will seem to originate in a completely
> different, generic place. Bad!
> 4) The compiler has no knowlege of the fact that the function is a special one,
> designed specifically to throw. So it can't detect dead code. It also can't
> "know" what you mean when you say assert(false).
> 5) Replacing a built-in _language_ facility with a hack is just ridiculous.
> That's why there is assert() in the first place.
> 
>>You are encouraged to code such a 'contract' in this manner instead ...
>> void Foo(int a)
>> in {
>>    assert(someExpensiveCheck(a)); // Removed in release.
>> }
>> body {
>>    // Input *data* validation.
>>    if (a == 42) Abend("In Foo(), the input data must be 42");
>>    /* rest of body */
>> }
> 
> Two things:
> 
> 1) Once again, it's not only about user-input validation. It's about validation of preconditions in general. These can, for example, be parameters that can come from anywhere. They can come directly from the end user, or from another programmer, or from a corrupted stack, or from god knows where.
> 
> But it doesn't even have to be parameters. It can be any sort of precondition. Having enough memory. A thread having stopped. A variable having been set. A mutex having been released. Anything. It makes sense to put these things in a section called "in," which is specifically designed to check for pre-conditions.
> 
> You mean to say all these things magically dissapear in production code? If that's the "philosophy," then that's quite dangerous and naive. It's exactly the _other_ way around, these things become more likely to happen (uncontrolled, distinct environment(s)) and much more likely to be seriously harmful (real, important data/systems at stake).

I agree that it is important to validate pre-conditions. D gives you two ways of doing it, and you can do both simultaneously. One is to do checking inside of in{} blocks which only occur in pre-release code, and the other is to do the checking in body{} blocks which can occur in both pre-release and release code.

If you specifically want checks done using assert then you must release 'pre-release' code. If you want these checks done in "-release" code then do not use asserts. I'm sorry that it is more cumbersome when not using asserts, but that's what's been implemented.

> 2) Also, why bother having an "in" section in the first place? This just creates a mess. You must split your "real" checks from the fake ones into two sections, when the "in" one could nicely handle both. This split would be fine for one function, but not for all. It's very distracting.

Totally agree.

> PS: As you can tell, I am pro-assert, and pro-in. In other words, pro-safety. You must always practice safe hex, people! ;)

I'm also pro-safety, thus I don't use assert() and in{} blocks to validate
function parameters (or other environmental dependencies); I use different
techniques.

-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
16/08/2005 2:15:52 PM
August 16, 2005
On Mon, 15 Aug 2005 22:13:10 -0600, Hasan Aljudy wrote:

> Derek Parnell wrote:

[snip]
>> 
>> Believe it or not, but this is a philosophical discussion.
> 
> Why then does the overview page say:
> "D (...) doesn't come with (...) an overriding philosophy."
> http://www.digitalmars.com/d/overview.html

I've often laughed at that usage. Walter's *philosophy* is liberally
sprinkled throughout D.

> and um, I think the word "philosophy" has different meanings in different context, and in the context of your post, it means "principle" or "idea"..

Maybe ... but I was more leaning towards the meaning of "belief system".
That is to say, it's what Walter believes how things ought to be. Other
people could have an alternate belief system that clashes with Walter's
one.

> so if we debate the meaning of "-release" it wouldn't really be a /philosophical/ discussion, because we're not debating the nature of time and space :P

Just the nature of 'Programming Done Well'  ;-)

>  From answers.com:
> http://www.answers.com/philosophy&r=67
> 2. Investigation of the nature, causes, or principles of reality,
> knowledge, or values, based on logical reasoning rather than empirical
> methods.

Yep, this is also what I meant. Not much in Programming Practice has been empirically proven. Somethings sure e.g. "goto increases the cost of maintenance" but not everything (yet).

> 7. A set of *ideas or beliefs* relating to a particular field or activity; an underlying theory: /an original philosophy of advertising/.

Yes to this one too.

-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
16/08/2005 2:48:03 PM
August 16, 2005
AJG wrote:

> The idea that asserts (or worse, contracts in general) are only useful to the
> immediate programmer is misguided.

The idea that asserts are to be used for anything other than development is misguided. I don't know your background, but the idea of compiling out asserts in release builds has been in practice in C and C++ for quite a long while. Assert is for validation of logic and *known* inputs (for example, validating that an arg is not null, or that an object was set to a specific state before the function was called), and not for unknown inputs (what Derek referred to as data - user input, scripted data, anything that isn't known at compile time). In C, whenever you need to validate unknown inputs you check it with an if block. Even Java has asserts now (since 1.4) because Java developers wanted something useful for development that could be compiled out at release (previously they had to if() everything). What you are trying to do is use assert in a manner that goes against its intended and standard use. It is not, in any language I know, meant for use in production code. Asserts are meant to be able to be compiled out, period.

The confusing part here is DBC. I agree DBC would be useful in production code. The in blocks can be used to validate both known inputs (assert) and unknown inputs (if(!condition) throw)). As it stands in D, DBC implemented on the same grounds as assert - for development purposes and not for release builds. But even so, you can get the same functionality now with if blocks, which is a much better option than assert abuse. An if block says 'I am meant to be here in production code' where as an assert says 'I am meant to be compiled out in production code'.

Just say 'No' to assert abuse!
August 16, 2005
Hi,

>AJG wrote:
>
>> The idea that asserts (or worse, contracts in general) are only useful to the immediate programmer is misguided.
>
>The idea that asserts are to be used for anything other than development is misguided. I don't know your background, but the idea of compiling out asserts in release builds has been in practice in C and C++ for quite a long while.

First off, D is not C, and D is not C++. D is supposed to be better than those two. C and C++, relatively speaking, are not safe languages. I hope that D would want to do better.

But, I'm going to play the devil's advocate:

On the linux side, I use GCC. GCC compiles asserts in by default. In fact, according to the C standard, asserts _should be in_ by default, so GCC is rightly following this convention.

In order to remove asserts, you specifically have to FORCE the symbol NDEBUG into your code. The verb "force" is not mine, it's in the very spec:

http://www.opengroup.org/onlinepubs/009695399/functions/assert.html

So, when I compile "release" code, I do something like:

gcc -Wall -Pedantic -O3 <code>

Whereas you would evidently do:

gcc -DNDEBUG (...)

See, that's _your_ decision. Just because you think so doesn't mean you should FORCE it upon the world. Specially when it reduces the safety of a function. I don't call that release code, I call that unsafe code.

Let's go over that one again:
Removing asserts unequivocally reduces the safety of a function. Period.

One last interesting bit is that even in -O3, the highest optimization level, asserts are _still_ left in the code (as they should) by the compiler. Therefore, asserts (and their safety) and optimization can be kept independent.

On the windows side, I use VC++. VC++ does something wonderful in the form of VERIFY. It's a version of assert that never goes away. That's what I always use and I love it.

Unfortunately, D doesn't have that. In fact, that would be a great compromise. If D were to introduce a permanent assert, e.g. verify(), then we could both have what we want.

> Assert is for validation of logic and *known* inputs
>(for example, validating that an arg is not null, or that an object was set to a specific state before the function was called),

There is no such thing as a "known" input. Are you telling me you know, in advance, _every_, _single_ way your function is going to be called in the future? Every possibility? Every programmer? Every project and program?

That seems a bit unlikely to me (Perhaps you are an oracle?). Therefore, it is unsafe. You don't know how and when your function is going to be called. Asserts are the guards that prevent bizarre calls from turning catastrophic. Leave them in! Or at least, let _me_ leave _mine_ in.

>and not for unknown inputs (what Derek referred to as data - user input, scripted data, anything that isn't known at compile time).

Oh, so then a "known input" is, by your definition, known at compile time. That's great. So I guess your asserts look something like this:

const int Foo = 42;
assert(1 == 1);
assert("car" == "car");
assert(Foo == 42);

Right? Well, those "known inputs" go into static asserts, not regular asserts. They would be _trivial_ as regular asserts.

>In C, whenever you need to validate unknown inputs you check it with an if block.

Maybe _you_ do that. That's verbose, more complex and less clear. OTOH, I use asserts for a lot of conditions that you might think will never happen, but, because of the nature of programs, you never know.

Just out of curiosity, what do you use asserts for, then? It must be for some truly trivial stuff, if I understand you correctly. Otherwise, if _not_ trivial, it is _wiped out_ in -release and all that non-trivial checking goes out the window. Do you see my point?

So which one is it, trivial asserts or useful asserts?

>What you are trying to do is use assert in a manner that goes against its intended and standard use. It is not, in any language I know, meant for use in production code. Asserts are meant to be able to be compiled out, period.

Once again, that's your opinion. All I am asking is for the choice to be left to the programmer independent of the code being "production" or not. One solution is the -contracts argument. Another would be the verify() version that doesn't go away. Either one would be fine by me. Both would be even better.

>The confusing part here is DBC. I agree DBC would be useful in production code. The in blocks can be used to validate both known inputs (assert) and unknown inputs (if(!condition) throw)). As it stands in D, DBC implemented on the same grounds as assert - for development purposes and not for release builds.

Agreed. DBC is good independent of "production" code as well. The -contracts argument would solve this problem.

>But even so, you can get the same functionality now with if blocks, which is a much better option than assert abuse.

You can also get the same functionality of switch() now with if blocks, which is a much better option than switch abuse.

That's not why I'm arguing. My point is that assert's syntax is nice and simple.

>An if block says 'I am meant to be here in production code' where as an assert says 'I am meant to be compiled out in production code'.

I don't like this "meant to be" mumbo-jumbo. Asserts are useful and elegant. So I use them and enjoy their elegance. If you don't like them, fine. Don't use them. Could the rest of us still keep them? Thank you.

>Just say 'No' to assert abuse!

Friends don't let friends compile without asserts. ;)
Asserts are the seat-belts of programming. You're not against seat-belts, are
you? :p

Cheers,
--AJG.



August 16, 2005
> For the tuning/tweaking crowd, a more fine-grained version could be
offered:

Yes even better :).

> Not sure what you mean. Which source?

Sorry the mars.c:385 frontend , it seems to turn on asserts when -unittest is given , though I haven't tried it or anything.

Charlie


"AJG" <AJG_member@pathlink.com> wrote in message news:ddrp8i$28b5$1@digitaldaemon.com...
> Hi,
>
> >I agree , I think contracts should be completely seperate from 'release'
and
> >'debug'.   Looking at the front end ( mars.c : 385 ) , it wouldn't take
much
> >at all , just an extra command line argument , -contracts or some such.
>
> I'm glad someone agrees. Another pro-safety feller I see ;)
>
> Indeed, a -contract argument would work well. Contracts should _always_ be enforced IMO. But I understand this isn't likely to happen. So, at least
the
> choice to enforce them should be given independent of debug/release.
>
> For the tuning/tweaking crowd, a more fine-grained version could be
offered:
>
> -contracts // all
> -contracts:in // preconditions
> -contracts:assert // asserts
> etc.
>
> >This has been talked about before , not sure what the outcome was.
>
> Walter?
>
> >Charlie
>
> >P.S. Also , in the source it has useAssert parameter set to true if unittests are on , maybe try that ?
>
> Not sure what you mean. Which source?
>
> Cheers,
> --AJG.
>
>


August 17, 2005
On Tue, 16 Aug 2005 14:50:43 +0000 (UTC), AJG wrote:

> Hi,
> 
>>AJG wrote:
>>
>>> The idea that asserts (or worse, contracts in general) are only useful to the immediate programmer is misguided.
>>
>>The idea that asserts are to be used for anything other than development is misguided. I don't know your background, but the idea of compiling out asserts in release builds has been in practice in C and C++ for quite a long while.
> 
> First off, D is not C, and D is not C++. D is supposed to be better than those two. C and C++, relatively speaking, are not safe languages. I hope that D would want to do better.

I think you missed the point. Other languages allow asserts to be removed,
so therefore D is not doing something that is thought as bad by many other
language designers.

> But, I'm going to play the devil's advocate:
> 
> On the linux side, I use GCC. GCC compiles asserts in by default. In fact, according to the C standard, asserts _should be in_ by default, so GCC is rightly following this convention.
> 
> In order to remove asserts, you specifically have to FORCE the symbol NDEBUG into your code. The verb "force" is not mine, it's in the very spec:
> 
> http://www.opengroup.org/onlinepubs/009695399/functions/assert.html
> 
> So, when I compile "release" code, I do something like:
> 
> gcc -Wall -Pedantic -O3 <code>
> 
> Whereas you would evidently do:
> 
> gcc -DNDEBUG (...)
> 
> See, that's _your_ decision. Just because you think so doesn't mean you should FORCE it upon the world. Specially when it reduces the safety of a function. I don't call that release code, I call that unsafe code.

This behaviour is identical to D, in that asserts are by default included and to exclude them you must do that explicitly.

Code is only unsafe if there are no checks in it, and one can do checking
without using assert().

> Let's go over that one again:
> Removing asserts unequivocally reduces the safety of a function. Period.

That is not universally true. I would have said 'removing checks reduces the detection of unsafe function behaviour'. The difference is that you seem to be saying that assert() is the only proper method to perform validation checks, but that is just not so.

> One last interesting bit is that even in -O3, the highest optimization level, asserts are _still_ left in the code (as they should) by the compiler. Therefore, asserts (and their safety) and optimization can be kept independent.

Just like D. The optimization switch does not effect asserts or contracts.

> On the windows side, I use VC++. VC++ does something wonderful in the form of VERIFY. It's a version of assert that never goes away. That's what I always use and I love it.
> 
> Unfortunately, D doesn't have that. In fact, that would be a great compromise. If D were to introduce a permanent assert, e.g. verify(), then we could both have what we want.

Yep. A verify() statement that works like assert() but is not removed by
"-release" *and* allows an additional coder specified message would be
useful for many people.

  verify(a == b, "Special message to user");

>> Assert is for validation of logic and *known* inputs
>>(for example, validating that an arg is not null, or that an object was set to a specific state before the function was called),
> 
> There is no such thing as a "known" input. Are you telling me you know, in advance, _every_, _single_ way your function is going to be called in the future? Every possibility? Every programmer? Every project and program?

Yes.

   a = sin(1.2)

In this case, the input is known (1.2), but that's not what you were
meaning was it ;-)

I repeat: function argument validation must not use D assert() statement or in{} blocks because they can be removed without the coder knowing it. For example, the Release or QA manager recompiles it with "-release" (by accident?).


> That seems a bit unlikely to me (Perhaps you are an oracle?). Therefore, it is unsafe. You don't know how and when your function is going to be called. Asserts are the guards that prevent bizarre calls from turning catastrophic. Leave them in! Or at least, let _me_ leave _mine_ in.

I repeat: assert() is not the only method to use for function argument
validation.

>>and not for unknown inputs (what Derek referred to as data - user input, scripted data, anything that isn't known at compile time).
> 
> Oh, so then a "known input" is, by your definition, known at compile time. That's great. So I guess your asserts look something like this:
> 
> const int Foo = 42;
> assert(1 == 1);
> assert("car" == "car");
> assert(Foo == 42);
> 
> Right?

Of course not. Now you're just being silly.

My assert usage is more like this ...

unittest{
   assert( myfunc(1.2) == 42.0);
   assert( myfunc(0.0) == 0.0);
   assert( myfunc(real.init) == real.init);
}

That is, I use them to validate that the function logic is correct by supplying known input values for which I know the correct results. If the function returns incorrect results then I assume that the function (or sub functions) is using the wrong algorithm.

Another usage is during specific debug sessions ...

  debug(REGRESSION) assert( data_in >= 0 );

where I'm testing prototype code for specific edge conditions or similar. Again, these are not expected to be released in a production edition because I would have handled these conditions by then. However they are useful for regression testing.

>Well, those "known inputs" go into static asserts, not regular asserts.
> They would be _trivial_ as regular asserts.

Duh!

>>In C, whenever you need to validate unknown inputs you check it with an if block.
> 
> Maybe _you_ do that. That's verbose, more complex and less clear. OTOH, I use asserts for a lot of conditions that you might think will never happen, but, because of the nature of programs, you never know.

Its because asserts can be removed *and* that they provide poor feedback to end users, that it is currently better to use the more verbose techniques.

I would rather

    real sqrt(real a) {
       validate( a >= 0, __FILE__, __LINE__, __TIMESTAMP__,
           sprintf("Cannot take the square root of (%s)."
                   " It must be zero or higher", a));

than

    real sqrt(real a) {
      assert(a >= 0);

any day. It provides much more useful feedback to developer and user alike.

> Just out of curiosity, what do you use asserts for, then? It must be for some truly trivial stuff, if I understand you correctly. Otherwise, if _not_ trivial, it is _wiped out_ in -release and all that non-trivial checking goes out the window. Do you see my point?

Yes, but I don't agree with you. My usage is not trivial as it validates
function logic. The logic doesn't change once it gets to the production
edition stage.

> So which one is it, trivial asserts or useful asserts?

Gee... let me think a bit ... Oh I know, I know, ... 42, right?

>>What you are trying to do is use assert in a manner that goes against its intended and standard use. It is not, in any language I know, meant for use in production code. Asserts are meant to be able to be compiled out, period.
> 
> Once again, that's your opinion. All I am asking is for the choice to be left to the programmer independent of the code being "production" or not. One solution is the -contracts argument. Another would be the verify() version that doesn't go away. Either one would be fine by me. Both would be even better.

I would support either or both these additions to D.

-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
17/08/2005 9:11:17 AM
August 17, 2005
Hi,

>> If D were to introduce a permanent assert, e.g. verify(), then we could both
>> have what we want.
>
>Yep. A verify() statement that works like assert() but is not removed by
>"-release" *and* allows an additional coder specified message would be
>useful for many people.
>
>  verify(a == b, "Special message to user");

Agreed. There you go, proof that there _can_ be agreement in internet newsgroups. I like your suggestion. In fact, an even better way IMO would be:

void verify(bool cond, ...);

That way it can tunnel parameters to work like writefln() does right now. E.g.:

verify(c == d, "c (%d) != d (%d)", c, d);

What do you think?

>> All I am asking is for the choice to be left to
>> the programmer independent of the code being "production" or not. One solution
>> is the -contracts argument. Another would be the verify() version that doesn't
>> go away. Either one would be fine by me. Both would be even better.
>I would support either or both these additions to D.

Awesome. Walter, any chance of these things happening?

1) A version of assert, that is never eliminated, in the form of:

void verify(bool cond, ...) /* throws VerificationError */;

2) A way to explicitly specify which contracts to include:

DMD -contracts (...) // Include everything.
DMD -contracts:in    // Include pre-condition contracts.
DMD -contracts:!out  // Include everything except post-condition contracts.

Or something similar (syntax is irrelevant to me).

Thanks,
--AJG.





August 17, 2005
In article <de00mc$889$1@digitaldaemon.com>, AJG says...
>
>Hi,
>
>>> If D were to introduce a permanent assert, e.g. verify(), then we could both
>>> have what we want.
>>
>>Yep. A verify() statement that works like assert() but is not removed by
>>"-release" *and* allows an additional coder specified message would be
>>useful for many people.
>>
>>  verify(a == b, "Special message to user");
>
>Agreed. There you go, proof that there _can_ be agreement in internet newsgroups. I like your suggestion. In fact, an even better way IMO would be:
>
>void verify(bool cond, ...);
>
>That way it can tunnel parameters to work like writefln() does right now. E.g.:
>
>verify(c == d, "c (%d) != d (%d)", c, d);
>
>What do you think?
>
>>> All I am asking is for the choice to be left to
>>> the programmer independent of the code being "production" or not. One solution
>>> is the -contracts argument. Another would be the verify() version that doesn't
>>> go away. Either one would be fine by me. Both would be even better.
>>I would support either or both these additions to D.
>
>Awesome. Walter, any chance of these things happening?

This wouldn't be hard to do right now.  Just write a function called "verify" and place it in object.d.


Sean


August 17, 2005
Hi,

>>Awesome. Walter, any chance of these things happening?
>
>This wouldn't be hard to do right now.  Just write a function called "verify" and place it in object.d.

But then how would I get line number and filename?

Thanks,
--AJG.


August 18, 2005
In article <de07m7$dke$1@digitaldaemon.com>, AJG says...
>
>Hi,
>
>>>Awesome. Walter, any chance of these things happening?
>>
>>This wouldn't be hard to do right now.  Just write a function called "verify" and place it in object.d.
>
>But then how would I get line number and filename?

Good point :p  I think there are actually preprocessor macros you can use for this purpose (__FILE__ and __LINE__) but it's annoying having to pass them as arguments.


Sean