Christopher Smith wrote:
Why not, since you just catch your errors and continue about your
business without exiting?
Wow. OK. We've hit strawman overflow here. Since you don't seem to be
actually reading my answers, I'm going to stop writing them.
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.
I do the same thing, except I write my own stack trace to my own logging
mechanism.
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++.
Yes.
> ... 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.... ;-)
Sure is! Just not mine!
I think it's way, way harder to have a C program with no buffer
overflows than a similarly functional Java program with no buffer
overflows. Wouldn't you agree?
I'd rather spend the time adding functionality and making the program
more valuable than writing code to protect myself from programming
errors, if someone has already done that latter part.
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.
No question there either. I'd be experimenting with Haskell right now if
it supported the kinds of things I need to do, like unicode, web access,
and so on.
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.
Yep. But not every program needs to get it right every single time. How
many applications are written, compared to how many STLs or GCCs?
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)".
Right. You don't. All you can do is reduce the number of places that you
do those things, and wrap stuff up in layers of checking code, and hope
you got all those places. By the time you can guarantee that you got all
those places (including in other peoples' code that you might not have
the ability to wrap up), you've written a safe language in C++, and
you're good to go.
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?
Then I'm in exactly the same situation you are with your entire program.
Except my unsafe libraries are small, and yours are the size of your
application, except to the extent that you implemeted a safe
subset/library and stick to it.
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.
In my experience it can be, yes. I mean, if the graphics artist in the
next cubicle complained Gimp dumped core once a week, would you say to
yourself "Gee, maybe his swap partition has a weak sector", or would you
say "Gee, there must be a bug in the Gimp"?
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
And in 100% of anyone else's code written in that language.
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.
I think you and I just have different experiences with this sort of thing.
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
Then you're not using a safe language.
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.
Yep. And Tcl, like Smalltalk and Lisp, has a syntax you can write and
explain on one page.
The fact that Java arrays are bizarre isn't due to the fact that they're
range checked, tho. It's due to the fact that Java hates data.
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.
But the ugliness of those languages isn't due to them being safe. It's
due to them being crappy languages.
Oh that's impossible. That's why you never find a garbage collecting
runtime implementing in C++.... oh wait.
It wasn't an accusation. It was a question. I've asked it many times of
many C++ experts, and every time I ask it, eventually the person who is
telling me about how easy it is admits it essentially doesn't work
without out-of-library (i.e., in the compiler) runtime support. Tell me
of a runtime GC in C++ that actually isn't just scanning thru memory and
keeping any page that any integer in some other page might be a pointer
for. I'd like to read how it's done without using "undefined" behavior
like indexing a pointer off an array to see what's stored in some other
instance's memory.
As far as I've been able to determine, reference counting is the only GC
mechanism that is supported without modifications to the runtime or
compiler by C++, and that isn't capable of handling arbitrary graph
objects. If there's a different GC mechanism that works, point me to it.
The "smart pointers" in STL aren't (as far as I can understand by
reading them) smart, except to the extent that assignment erases the
source pointer, yes?
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?
I write it in Smalltalk (as originally designed) or Hermes or something
like that, where the files *are* the objects! ;-)
Or, when done with the graph, invoke the GC manually and have it close
the open files for you.
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.
Me too. But it takes me a lot more effort to get that right than it does
using a higher-level language. It's a shame there aren't more
programmers of our quality out there, or there would be far fewer buffer
overrun security holes.
Object foo = new Object();
if (foo == null) {
//it you reach here, dumping and exiting is a good idea
}
If you actually code checks for that sort of thing in your C++ code,
you're spending a lot of time you could be using more productively,
methinks. :-)
(Yes, I know that particular example isn't impossible in C++.)
Okay, how about that it will accomplish much the same results as your
"safe" languages?
Sure. If you program very defensively in C++, you can get some code
that's pretty robust vs programmer error, assuming the programmers stick
to using the stuff you designed. The latter part is hard. It's *harder*
to do it right than wrong. In a safe language, you have to go out of
your way to circumvent the mechanisms that keep you from shooting
yourself in the foot too hard.
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.
I think I already gave a few examples. Go visit a web page with broken
javascript code and watch your browser not dump core. I also explained
how I handle the errors, and it seems to work just fine for me. I had
been halfway through an extensive description of another system I did
way back when, and I realized you'd probably just say "well, that was an
expected error."
--
Darren New / San Diego, CA, USA (PST)
His kernel fu is strong.
He studied at the Shao Linux Temple.
--
[email protected]
http://www.kernel-panic.org/cgi-bin/mailman/listinfo/kplug-lpsg