-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Darren New wrote:
> Christopher Smith wrote:
>> Well, you could provide a nice message back to the customer, or you
>> could be presenting them with someone else's credit card number. ;-)
> 
> Errr, no, I wouldn't think so, since the other person's credit card
> wouldn't be in their address space, right?

Why not, since you just catch your errors and continue about your
business without exiting? Heck, particularly with garbage collection
that memory is going to hang around for a while.

>> get messed up anyway, but you have a good chance that the problem only
>> exists in your process.
> 
> Sure. And I have a good chance that in my program, the problem isn't one
> that would keep my error handling from running correctly. Of course, if
> it is, then I fall back to your solution, and exit.

I guess it depends on your development process. We try to cover
anticipated error conditions, and when an unanticipated one shows up, we
 normally get a core file, learn about the problem, and either eliminate
it or add it to the list of anticipated error conditions. This tends to
leave us with hardware problems being the most likely cause fairly early
on in the software's lifecycle.

>> Huh? How do you know that you'll get an error when something happens
>> that shouldn't?
> 
> Depending on what you mean by "error" and what you mean by "shouldn't",
> of course I don't. But I know it more than you do, using C or C++. There
> are a whole range of common errors it's impossible for me to encounter
> using a safe language.

Despite it being implemented in C or C++.... Careful, someone might
reach the conclusion that it is possible to have a C or C++ application
that doesn't have a whole range of common errors.... ;-)

Look, I could poo-poo over your Ada, Tcl or Java (Java in particular
largely trades one set of common errors for another) and point to
Haskell or ML as *really* reducing the set of common errors down to a
small number.

>>> But if you don't have a way to catch errors in the first place (such as
>>> array bounds checking, bounds checking on integers, and so on)
>>
>> I assure you that C++ is capable of doing such things.
> Sure, but you have to get it right Every Single Time.

Actually, every language needs to get it right every single time.

>> written in C or C++. ;-) It's nice when a language does this stuff for
>> you, although it can be annoying when you can't turn it off when it gets
>> in your way, but then you can always switch to an unsafe language. ;-)
> Yes, exactly my point.

Perhaps we aren't in disagreement then. I had thought your point was
that if you are using C or C++ that you "don't have a way to catch
errors in the first place (such as array bounds checking, bounds
checking on integers, and so on)".

>>> If you're relying on a core dump to detect an error, my process will
>>> dump core in exactly the same way as yours does if there's an error in
>>> stdio or something.
>>
>> Nah, 'cause your code will turn it in to an IO exception or a null
>> pointer exception, etc., unwind the stack a bit until it thinks it can
>> start all over again.
> 
> Well, not if there's an error in the interpreter. If an unsafe library
> generates a segv, I'll get a segv.

What if an unsafe library corrupts memory without generating a segv?

> And since you can catch signals in C, you're not guaranteed you'll dump
> core either. So again, I don't see what the difference is.

Yes, but I wouldn't be so foolish as to suggest that you do so unless
you know what the error is.

>>>> Sure, but there are far more subtle errors that pretty much or only
>>>> going to show up in the form of your code finding itself in an
>>>> unexpected state.
>>> Certainly. I've had bad sectors in swap space.
>>
>> That is not exactly a subtle error.
> 
> You would be amazed. When's the last time you checked your swap space
> for errors?  What if there's a read error one out of say 1000 times?

Oh, I know it happens. I'm just saying that it is not exactly subtle.

> Except the "unsafe" portion of my code is either extremely well tested
> (not unlike relying on the kernel) or a tiny portion of my code. If I
> very carefully craft the 2% that's unsafe and go hog wild on the 98%
> that's safe, I can be much more productive than if I have to carefully
> craft the 100% of the application.

Yes, I have much the same experience, though in my case it applies just
as much to my C++ code as stuff I write in other "safe" languages.

>> Why do you need a range-checking *language*.
> 
> To ensure that the range checks actually get checked everywhere.

No, you mean to ensure that it gets checked in 98% of your code while
leaving the 2% of your code without such certainty. Either that or more
than 2% isn't checked, but at least then you have it well tested. Sounds
a lot like my code (well, except for the not being well tested part ;-).

> The same reason you want your compiler to enforce the syntax of your
> language, and the type checking, and so on. It reduces the number of
> unsafe places you need to check for unsafe behavior to just those places
> that *need* to be unsafe.

Sure, but unfortunately it still means little bits "unsafe" code run
around and potentially invalidate notions of the "safety" of the rest of
your code.

>> In C++ it is not at all uncommon for folks to use collections and
>> iterators that do range checking. It is done in the library, rather than
>> in the language, following the pearl of wisdom that if you can do
>> something in a library instead of the syntax of a language, it's a good
>> thing.
> 
> Sure. Until some unsafe library clobbers your collection somewhere else,
> and you start getting stuff out of the collection that you never put in,
> and you spend a month tracking down what's going on. BTDTGTTS.

I have to admit, that is one of the disadvantages of C++. If I were
using a "safe" language, I would only be worried about some unsafe
library that clobbers my collection somewhere else and I start getting
stuff out of the collection that I never put in, and I spent a month
tracking down what's going on. I got a whole closet of t-shirst from
that, not to mention a great living as a consultant.

>> I think you missed my point. I'm not questioning that automatic range
>> checking is useful. I'm just questioning why it has to be embedded in to
>> the definition of the syntax of a programming language.
> 
> It's not embedded in the syntax of the languages I use that are safe.
> Neither Tcl nor Smalltalk (for example) define a syntax for arrays. I
> wouldn't say it's in the "syntax" of Java either. Java just defines what
> happens. My language is my library, and I don't make a really big
> distinction between the two. That Zen bit again.

You ought to, as there are very good reasons to distinguish. Smalltalk
keeps the language very small and the library big, and it is a great
asset. Java doesn't, and as a consequence Arrays are this weird
aberration relative to other containers that make all kinds of things
difficult.

>> I write C++ code
>> that automatically checks against range boundaries, null pointers,
>> integer overflows and all kinds of other badness. Indeed by doing so I
>> can automatically catch a lot of errors that go undetected in a number
>> of "safe" languages without manual coding.
> 
> You mean, you use libraries that other people wrote?

Sometimes I use the code of others. Sometimes I use my own.

> Because otherwise, that's manual coding.

Ugh. Again with the semantics.

Fine, you got me. It's manual coding. I manually write it once, work on
getting it right once, and then never worry about writing it again.
It is also a hell of a lot less code and a hell of a lot less error
prone code than I'd write in a number of "safe" languages.

> And if you're using libraries others wrote for this, how do you know
> they're right and safe?

I don't. Hence being a fan of dumping core if one of these things
triggers an error.

> And, on the subject, how do you build a data structure that's an
> arbitrary graph in C++ and still manage to garbage collect it when
> you're done with the last reference to it?

Oh that's impossible. That's why you never find a garbage collecting
runtime implementing in C++.... oh wait.

Here's a better question for you... if said graph is made up of nodes
that have open file descriptors to files... how do you make sure you
close all those file descriptors as soon as you are done with your graph?

>> Safe language != stack never gets corrupted. I can tell you this from a
>> lot of first hand experience.
> 
> Bad implementation of safe language might mean stack gets corrupted. Bad
> implementation of OS means files get corrupted. So? How likely is that,
> compared to a bug in your code?

Bugs in my code are of course very common. Bugs that produce the kind of
unexpected errors like a null pointer where there shouldn't be one...
not so much. Bugs that exercise undefined parts of a language? Damn rare.

>> Actually, just the opposite. If I have a "safe" language, and I find a
>> value or condition that is defined to not be possible, I actually have
>> all the more reason to assume the worst.
> 
> Uh, like what? Sure, if you have something defined to be impossible,
> then it's a good time to exit. But I can't think offhand of any
> condition defined to be "impossible" in the languages I know of that's
> ever likely to come up. That's kind of what a "safe" language means -
> there's a defined result for anything you can do within the language.

Object foo = new Object();

if (foo == null) {
    //it you reach here, dumping and exiting is a good idea
}

>> Now you can avoid that error in C++ (not to mention abusing pointer
>> arithmetic). You're welcome.
> 
> If you're not going to grant me that a safe language can be relied upon
> to not produce "impossible" results, why should I grant you that the
> code you just supplied will actually prevent null pointer exceptions?

Okay, how about that it will accomplish much the same results as your
"safe" languages?

>>> I'm not sure why recovery code at the top level of the stack needs to be
>>> held to a higher standard than recovery code lower down.
>>
>> Well, it depends on what you mean by "lower down", but hopefully code
>> that is local to the error understands the nature of the problem and can
>> correct it or at least avoid it.
> 
> Sure, if you think of it. That's the goal of catching the unexpected
> errors - to fix the code so they're expected errors.

It's pretty tricky to fix an error you don't expect. I'd really like to
see an example of how this works for you.

- --Chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGbgUoOagjPOywMBARAtaRAKC3mTfwByGi9Ecau5syN6ZhwJEINgCg+f76
V04/fxwXwDvQbQxp6YmtywY=
=KviJ
-----END PGP SIGNATURE-----

-- 
[email protected]
http://www.kernel-panic.org/cgi-bin/mailman/listinfo/kplug-lpsg

Reply via email to