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

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



On Fri, Jan 04, 2002 at 11:50:04PM -0600, Gary Turner wrote:
| On Fri, 04 Jan 2002 14:28:46 -0500, dman wrote:
| >On Thu, Jan 03, 2002 at 09:39:09PM -0600, Gary Turner wrote:
| >| On Thu, 03 Jan 2002 17:34:00 -0600 (CST), Richard Cobbe wrote:
| >| >Lo, on Thursday, January 3, Erik Steffl did write:
...
| >| >Type safety (plus dynamic allocation) implies advanced memory
| >| >management.  The converse is not true: you can slap Boehm's conservative
| >| >GC onto a C++ program, but you can still get segmentation faults:
| >| >
| >| >    char str[] = { 'b', 'a', 'd', ' ', 's', 't', 'r', 'i', 'n', 'g' };
| >| >    // note the lack of a terminating '\0'!
| >| >    cout << str;

| >| This example looks to be a cheat, in that you've defined an array and
| >| then treated it as a string (legal).  Had you defined a string, it would
| >| be null terminated and index addressable.
| >
| >He did define a string.  In C++ there are 3 ways of defining a string
| >(in C there are 2).  There is "char[]", "char*" and "std::string".
|
| Isn't 'char*' redundant, since an array var is a pointer by definition?

Almost.  A char[] behaves like a char*, but you can't assign to a
char[] the way you can with a char*.  Eg :

    char  t[5] ;
    t = malloc( 6*sizeof(char) ) ;

The assignment yields
    incompatible types in assignment
when you try and compile it.

| If I'm showing my ignorance again, I apologize.
| >The latter is the best way because it provides the most protection.
|
| I disagree.  He defined an array of characters, just as 
|     int a[] = 1,2,3;
| is an array of integers.

Right.  But the point is the type system is more than that.  

| To define a string he should say
|     char a[] = "bad string";

This would work, but how is this _type_ different from the type above?
Both are char[]!.

| or
|     char a[11]; 

Nope.  This gives you contiguous space for 11 chars, but doesn't
initialize it to any value (or ensure it is NUL-termiated).

| Either of these forms would give him a properly terminated 'string'.

Meaning that if you dance just right, the invariants are met, but if
you slip a little, BOOM!

| Without the terminating \0, string functions will go merrily gonzo.

Right, that is part of the invariant on C-strings.

| >| The fact that you *can* screw up doesn't mean you have to.
| >
| >True, but when choosing a language for a given project, wouldn't you
| >rather use one that gives you fewer guns to shoot yourself with?  I
| >know I would :-).  (this is not to say that C is not a good language,
| >but it does have its place)
|
| Isn't that true of any tool?

Yes.

| is still the writer's responsibility to honor the function's
| expectations and create the necessary error checking routines before
| they shoot the wheels off.

If they can.  You can't check a random char* or char[] to ensure it
is a valid string.  If you could, then the string functions would and
they wouldn't segfault.  (Think : if the block of memory ("string")
doesn't contain a NUL character, how do you know where the block of
memory ends?)

| >| In the example above, is it a type, or allocation error if the
| >| *programmer* decides to access str[10]?  (If I counted right, that's
| >| the next byte after the array bloc.)
| >
| >I think that would be an allocation error since it is illegal to
| >access memory outside the allocated bounds.
|
| It would be nice if c/c++ included array bounds checking, but since it
| doesn't, the programmer *must* check and control it himself.  The array

It is impossible to check it at runtime.  See above.  To work around
this, you can avoid arrays altogether and use, for example GList from
the GLib library.

-D

-- 

In my Father's house are many rooms; if it were not so, I would have
told you.  I am going there to prepare a place for you.  And if I go and
prepare a place for you, I will come and take you to be with me that you
also may be where I am.
        John 14:2-3 



Reply to: