[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: OT: Language War (Re: "C" Manual)



Lo, on Monday, December 31, Erik Steffl did write:

> "Eric G. Miller" wrote:
> > 
> > On Mon, 31 Dec 2001 13:46:15 -0800, Erik Steffl <steffl@bigfoot.com> wrote:
> > 
> > > Richard Cobbe wrote:
> > > >
> > > > Lo, on Sunday, December 30, Dimitri Maziuk did write:
> > > >
> > > > > * William T Wilson (fluffy@snurgle.org) spake thusly:
> > > > > ...
> > > > > > So... why *should* the programmer concern himself with
> > > > > > individual bytes of memory? (Assuming he is writing an
> > > > > > ordinary application and not a hardware driver or something
> > > > > > similar).
> > > > >
> > > > > Because if he does not, his application will segfault and dump
> > > > > core.
> > > >
> > > > No.  This level of concern is necessary only for non-type-safe
> > > > languages.  It is provably impossible for a program written in a
> > > > type-safe language to segfault (assuming that the language's
> > > > run-time system is implemented correctly, of course).
> > >
> > >    ???
> > >
> > > it's the resource allocation that's important, not types. garbage
> > > collectors are generally more robust as far as segfaulting (and
> > > similar errors) go (of course, just because the program doesn't
> > > segfault it doen't mean it's working correctly). the other
> > > important factor is how much runtime check language does
> > > (e.g. checking for array boundaries etc.)
> > 
> > But it's the type safety of the language that prevents the abuse of
> > memory, not how it was allocated.  Strong typing eliminates a huge
> > number of error cases.  C and C++ both subvert the ability of the
> > compiler to do static type checking via casts and void pointers.
> > Strong static type checking also has the possible advantage that the
> > compiler can better optimize the generated code.
> 
> consider perl which doesn't have strong types but it's quite
> impossible to make it segfault and C++ on the other side which is
> fairly dangerous even without casting (I would even go as far as
> saying that casting makes no difference (statistally), but I'd have to
> think about it).

Perl does have strong types, but they don't really correspond to the
types that most people are used to thinking of.  Perl's types are

    * scalars (no real distinction between strings, numbers, and the
      undefined value)
    * lists
    * hashes
    * filehandles

(I haven't really used Perl since Perl 4, so this list may not be
complete.)

> most of the segfaults are because of the resource allocation mistakes,
> not because of mistaken types... at last that's my impression.

Resource allocation mistakes (at least, the kind that typically lead to
seg faults) *are* type errors, from a certain point of view.

Consider the following:

    char *a, *b;

    a = strdup("This is a sample string");
    b = a;

    free(a);

    /* Much code follows here, none of which modifies b. */

    printf("%s\n", b);

This may or may not segfault, but it's obviously not correct.  The
problem is, in fact, a type error in the reference to b in the printf()
call.  The compiler and library think that b is a pointer to a
null-terminated character string, but this is in fact not the case.  In
a type-safe language, you would not be allowed to bring about this state
of affairs.

> also note that in java you have to cast (when getting items from
> containers) but it doesn't make java programs more likely to segfault.

That's because Java's typecasts are safe (i.e., checked at run-time):
they're equivalent to C++'s dynamic_cast, not static_cast.  (Casting a
float to an int, of course, is equivalent to C++'s static_cast, but
errors with those sorts of casts are not likely to cause memory
problems.)

> > >   and as far as runtime system goes - only interpreted languages have
> > > runtime systems.
> > 
> > Well, I dare you to remove 'ld' or 'libc.so' and see how many programs
> > run ;-)  I think it's fair to characterize required language libraries
> > as part of the "run time" system.  Whether or not a program is statically
> > compiled is unimportant, as the language library still performs actions
> > at runtime that "your" program depends on, and which "your" program
> > could not function without.  Among those things, might be checking
> > array accesses and raising exceptions for range errors...
> 
> IMO the important distinction is whether the program runs itself
> (compiled programs) or whether it is run by other program, which
> controls it and takes care of various runtime checks etc.

Performing run-time checks, as with array indexing, does not necessarily
imply the existence of an interpreter.  If a compiler sees the
expression a[i], it can either assume that i's value is a valid index
for the array a (as C and C++ do), or it can insert the appropriate
checks directly into the executable code.  I still claim this is part of
the language's run-time system, regardless of how it's interpreted.

> you do not necessarily need ld and standard libraries for c or c++
> program, however you need vm for java program.

Oh, I don't know, I'd say that ld is pretty essential!  (It may not be
necessary for statically-linked binaries, but I don't know for certain.)

And, in fact, you don't necessarily need the JVM for Java, either.  I
believe there are some compilers out there which compile Java straight
to native machine code.  And, for a while, Sun was talking about
implementing the Java bytecodes in hardware, so the Java .class files
would *be* native machine code.  (I'm not sure if that effort ever saw
the light of day or not.)

> or, in other words - runtime for compiled program is HW, runtime for
> interpreted program is SW (HW usually provides generic, basic &
> low-level functionality, SW usually does provide higher level
> functionality, specific for given language).

Some final thoughts:

1) If that's how you define runtime systems, then how do you explain the
   code necessary to support exception handling under C++?

2) How do you explain those compilers that compile Java straight to
   native machine code?  There's a lot of support that has to be
   included in the resulting program, like GC, synchronization
   operations, and exception handling.

3) Just an interesting idea, but from a certain point of view, *ALL*
   programs are interpreted: it's just a question of where the
   interpreter is.  For your standard binaries, the interpreter is
   implemented in hardware.  For Java, it's in software.

Richard



Reply to: