C/C++ style Crashes?
Sebastian Biallas
groups.5.sepp at spamgourmet.com
Fri Jan 12 12:10:49 PST 2007
Alexander Panek schrieb:
> Sebastian Biallas wrote:
>>>> [...]
>>>> It just doen't solve the problem that you have a bug in your program in
>>>> the first place. Reread that sentence.
>>> Exceptions can be handled at runtime, still. try (to) catch it and there
>>> you go. :)
>>
>> So, how exactly do you /handle/ an exception which "should not be there"?
>
> One has to make sure to catch all "should not be there" exceptions, too
> (ideally). In the real world, of course, there can happen to be mistakes
> in the code, hidden bugs and what not else. But the fact is, that in
> most software, that is really fully tested, those happen very rarely and
> can be handled with special routines -
By what routines?
> maybe also automatically sending
> a bug report to the developers or the IT department of a company.
You can do this with C code, too (see talkback from mozilla)
> This
> depends on what kind of software you write/use(libraries). Apart from
> that, D has this neat scope(fail) thing, that will cover almost all
> circumstances, except segmentation faults .. ;)
scope(xx) is nice, that's right.
>>>> Getting an unexpected exception in a shipped application is a huge bug.
>>> That's why you always /test/ everything so good, that you just don't get
>>> unexpected exceptions.
>>
>> Well, so you shouldn't need exceptions at all for array handling, right?
>> (Except for debugging, where they really help)
>
> As soon as the amount of /dynamic/ data you have to handle grows, I
> don't think there's a way around using at least exceptions to stay safe.
I'm not sure I understand that sentence.
Maybe I should clearify my point:
Exceptions are a nice way to handle unpredictable situations at runtime,
like an IO error. Java helps you even with this, when you use the
throw() specifier for your io-functions.
But exceptions are IMHO a wrong way to handle /programming mistakes/.
Programming mistakes must be fixed by a programmer -- they can't be
fixed at runtime. It's just too late if a buggy program is running.
>> So what to do now? The program is now in an unstable state.
>> And even if you catch the Exception on the right place: The Exception
>> should never have been thrown. There is a bug, and the bug is not
>> necessarily at the place where the exception was thrown -- the program
>> might have been in an inconsistent state for hours.
>
> This is, of course, not so good. But then again, you should design the
> software in a way that avoids such circumstances (yes, this is not
> possible in any cases, but in very much).
This is pretty much the answer you get from someone advocating C or C++
if you ask him why a C or C++ program behaves in such an unpredictable
way ;)
>>> They worked for me
>>> pretty well so far to avoid a unhandled exceptions that just terminate
>>> the program.
>>
>> It would be even better if the compiler could prove at compiler-time,
>> that there are no OutOfBound, NullPointer and CastExceptions possible.
>
> AFAIK, D handles this as long as it's not dynamic data. As soon as array
> indexes, pointer arithmetic or other not so exotic things kick in,
> there's no way to determine what values/states there can be.
You need a careful designed language for this. See e.g. SPARK (I haven't
used it yet).
>>
>> While this is hard for ArrayOutOfBounds, there are quite easy ways for
>> avoiding NullPointer and CastExceptions at all. In the language Nice[1]
>> they do this as follows:
>>
>> NullPointer: They have different types for pointers that can be null
>> (?Type) and pointer that can't (Type). You can't dereference a ?Type
>> variable.
>>
>> So, let's say we have
>>
>> void foo(?Type t)
>> {
>> // we want to dereference t
>> if (t != null) {
>> // now the compiler "magically" converts t to type Type
>> t.doSomething();
>> }
>> }
>
> How about:
>
> void foo ( Type t )
> in {
> assert( t != null );
> }
> body {
> t.doSomething();
> }
>
> I find this rather equal.
It is rather equal. The difference is not in the source code, the
difference is how you /can/ write this.
In Nice you just have this one possibility: If you want to dereference a
?pointer, you have to test it against null -- otherwise it won't
compile. In other languages this test is optional (and even whether a
pointer can be null is not part of the language but of the
documentation. And documentation is often not available or wrong).
Of course you can write correct code in D and other languages. The point
is: In Nice the code is guaranteed to be correct regarding null-pointer
checks once it compiles! There is no need of a "style guide" for this
which will be ignored once the project reaches its deadline.
>> TypeCasts: You don't cast with a cast-operator, but with a
>> instance-of-expression:
>>
>> void bar(A a)
>> {
>> if (a instanceOf B) {
>> // now a is of type B, no need to cast
>> }
>> }
>
> What exactly does an instance-of-expression? Never seen this, actually.
if (a instanceOf B) {
is the same as
if (dynamic_cast<B>(a)) { // in C++
or
if (cast(B) a) { // in D
More information about the Digitalmars-d
mailing list