Re: c / c++ : is it end of era ?



jacob navia said:

Richard Heathfield a écrit :
jacob navia said:


Richard Heathfield a écrit :

jacob navia said:

<snip>

it is not
very difficult to find problems with the approach in C to many things,
since the bugs in the language aren't that difficult to find.


Do you have at least two examples that will stand up to close scrutiny?


Well, I hope we can start a constructive discussion, instead of
flame wars.


When you start talking about "bugs in the language", you're not trying to
start a constructive discussion - you're trying to start a flame war.
Nevertheless, if you can find some serious bugs in the language, that's
important enough to merit serious and indeed constructive discussion. But
if you're just being silly, well, that's just silliness. Let's find out
which it is, shall we?


The most glaring bugs in C are:

1) Zero terminated strings.


That's not a bug. It's a design decision. You might not agree that it's a
good decision, but it's a conscious, deliberate decision nonetheless.

No bugs so far.

<snip>

Any bug can be converted to a "design decision", since a design that
is at the root of COUNTLESS buffer overruns, virus attacks, etc, is
obviously correct.

And any design decision can be called a bug. For example, the whole of
lcc-win32 can be called a bug. So what? The fact that you can abuse
null-terminated strings doesn't mean that null-terminated strings are a
language blemish. You can abuse anything if you try hard enough.

2) Confusion between pointers and arrays.

What confusion? I don't get them confused, and neither does anyone who
has taken the trouble to learn the language.

Of course (see above). This is not a bug, it is a "conscious design
decision". Nevertheless, it is not immediately obvious to anyone outside
the C pros, why [...] prints:
sizeof array is: 4

Nor is it immediately obvious to a newbie guitarist that guitar music is
written an octave high. I once knew a newbie guitarist who had broken
dozens of strings because of this, and yet he remained convinced that he
had to pitch his strings in such a way that he could play the music as
written. It took a long time to convince him otherwise. The ignorance of
the newbie is not the best yardstick for whether language features are a
good idea or not.

Ahhh. OF COURSE. Arrays "decay". This is a C only concept.

Not true. It's also true, for example, in C++.

And this needs surely a lot of convoluted explanations
as the countless C-FAQ prove.

No, it's all perfectly straightforward, and is explained very clearly in
K&R2. Anyone with the nous to read that is not going to struggle for long.

Arrays in C are completely
screwed up. There is endless confusion between pointers and
arrays specially because the size information is destroyed across
function calls.

No, array information is never destroyed. It isn't always *conveyed*, but
it is never destroyed except when the array is destroyed.


Yes of course, since when I pass the array in the program above
it is just not passed as an array, even if C has pass by value
semantics...

The expression's value is passed. Before that value is passed, it has to be
calculated. In your example, the value of the expression consisting solely
of the name of the poorly-named 'array' array is the address of the first
element of the array, and that element's address is passed by value, its
type being pointer-to-int. That your poorly-prototyped function doesn't
make it clear that it is receiving a pointer-to-int because it uses ancient
syntax, does not change the fact that what is being passed and received is
a pointer.

Then pedantic people will say that all is well since if the arrays
aren't passed as arrays but as pointers by definition, the sizeof
still works ok.

The array isn't passed at all! What is passed is an expression's value.

But everyone else understands that in the above example function "fn"

The example function was poorly written, and does not serve as a good
example.


No bugs so far.


Of course. Only "conscious design decisions", like trigraphs...

Right.



3) From (1) and (2) we obtain as a consequence the inherent
impossibility to make bounds checks when accessing arrays and
strings. This leads to endless bugs.

Since both your premises are false, what hope is there for your
conclusion? But the lack of bounds checking in C does not in fact lead to
endless bugs. What leads to endless bugs is "not knowing what one is
doing", and that is true for any programming language and indeed any
engineering discipline.

Of course.

C programmers never have bugs, since, if someone has a bug, it is not
"knowing what he is doing", hence he is not a C programmer.

More usefully, if one's program has a bug, it means that the programmer does
not understand his program. (This may be because he doesn't understand the
rules of the language, or it may not.) The way to get rid of the bug, then,
is not to change the program or the language, but to increase the
programmer's understanding of his program. Once he understands it fully, he
will see why it does not do what he intends.

Obviously
only Mr Heathfield qualifies as a C programmer then (maybe with the
company of Mr Dan Pop, that also told me that he never had a bug...)

See above. Anyway, I doubt very much whether Mr Pop would have told you
that. He's far too sensible.

The fix is proposed in lcc-win32: a few improvements to the language and
we can get rid of zero terminated strings and arrays as pointers.


Getting rid of zero-terminated strings is not a fix or an improvement.
Removing choice is not the best way to persuade a C programmer that
you're on his side.

Who told you that C strings aren't supported? They are supported OF
COURSE.

So you're getting rid of them *and* supporting them? What colour is the sky
on your planet?

What I do is to give programmers the choice PRECISELY. The can now
choose between C strings or the String library. In YOUR world there is
NO OTHER CHOICE but C strings!!!

Sure there is. If you don't like C strings, there are lots of string
libraries out there, all with varying designs, performance characteristics,
etc. Lots of choice. Me? I use one I wrote myself. Why? Because I know I
can move it around the place. What I can't do is write a program that uses
lcc-win32-only features and *guarantee* that I can move that program to
another computer (say, for example, the S2/NX) and still have it work,
straight out of the box, on that machine's native conforming C compiler.


And arrays are not pointers, so you can't get rid of "arrays
as pointers".


Yeah, of course I can.

No, you can't. This is very, very simple.

Arrays are not pointers.
Therefore there is no "arrays are pointers" feature.
Therefore you can't have got rid of such a feature.

The absence of such a feature does not mean you have got rid of it. It can
mean that the feature never existed in the first place, and that's what it
means here.

Look at lcc-win32.

Your utter inability to understand simple logic does not make a good
advertisement for your product.


Another big problem is the error-prone malloc/free combination.


Why is that error-prone?


Because humans are not machines, and the human circuit (i.e. the brain)
is not a computer, but a vastly more complicated circuit than any
computer in existence.

This does not explain why malloc/free is error-prone.


Such a circuit is able to build circuits (something computers
aren't able to do) and is able to program computers (also
something computers aren't able to do) but it is ERROR PRONE, i.e.
due to the way the brain ciruitry works, it is not able to reproduce
a lot of mechanical acts without sometimes FAILING.

This, again, does not explain why malloc/free is error-prone.

If I tell you to add thousands of digits thousands of times
you WILL make a mistake, even if you are an expert.

So what? If I tell you to write int main(void) by hand thousands of times
you WILL make a mistake, even if you are an expert. That does not mean int
main(void) is error-prone.

If I ask you to keep track of thousands and thousands of memory areas
and never make a mistake when releasing the allocated memory you
WILL make a mistake even if you claim here that it will never
happen to you.

I would claim no such thing. I would, however, claim that tracking such
things down is not nearly as difficult as you imagine.


The problemof malloc/free is that it is not scalable. You can get away
with it in small systems, and in single threaded applications.

In a multi-threaded complex application, where there are thousands or
millions of allocated pieces of memory it is another, completely
different story...

You have not demonstrated your case. You have, however, provided some
evidence for eschewing multi-threading, which is non-standard in any case
and, as you say, enormously increases the complexity of an application for
no real benefit.

We have
discussed this here several times.


Yes. When you want memory, you ask for it, and if possible you'll get it.
And when you're done, you give it back.

How do you know when you are done?

When you've given back the last piece that you received.

That is precisely the question. You have to know exactly when each piece
of memory is needed, and when not. Since it is SO EASY to make an alias
in C, how do you know that in all that complex code there isn't an
alias for this piece of memory???

Because I understand the program, either because I wrote it or because I've
taken the well-remunerated time to study it long and hard.

What could be easier?

Easier would be:
"When you want memory, you ask for it, and if possible you'll get it.
The system will detect when you are done with it and
release it."

That IS easier...

Slower, too. And unpredictable. And not portable.




How is this
"error-prone"? You have never satisfactorily answered this.


I can't answer it for you since you claim never to do a mistake...

I don't recall saying any such thing, ever. Please cite the message ID to
which you refer.

For all other people however, the reasoning is obvious.

I make mistakes just like anyone else, and that includes sometimes
forgetting to release memory that I allocated. Unlike you, however, I don't
see this as being a huge problem, because it's easy to detect and easy to
fix.

The solution is to use an automatic
software component (garbage collector) that manages the release of the
allocated memory.


Memory management is too important to be left in the hands of the system.

Nobody takes memory management from you. Just the finding of unused
memory is taken from you.

That's a contradiction in terms. Memory management includes deciding when to
release a memory resource.

It is still the programmer that allocates
memory. This is like saying that an automatic car doesn't let the driver
drive the car...

No, it's like saying an automatic doesn't allow the driver to manage the
gear-changing process as effectively, which is why many racing drivers
prefer manual gearboxes even though automatic transmission in racing cars
is far superior to that in works cars.

Note that the objective here is not just to say what is wrong but to
propose solutions.


Let me know when you find something wrong.

Nothing is wrong Heathfield.

Fine, so what's all the fuss?

For programmers like you that never make mistakes nothing is wrong.

Oh, but I do make mistakes. So what?

I am speaking for the other ones like me that DO make mistakes.

The kind of mistakes you're talking about are trivial and easy to correct.
The kind of mistakes you *make* (in Usenet articles) are also trivial and
easy to correct, but unfortunately this involves knowledge and experience
of the C language and a mastery of elementary logic which your articles do
not demonstrate that you possess.

Nothing you have mentioned so far
constitutes a "bug" in C.

There isn't a blinder man than the one that doesn't want to see.

Okay, do you want to see? Here we go:

Null-terminated strings were a design decision. If you don't like it, by all
means use something else, but be sure to keep the source code around
because otherwise it'll be hell to port.

Arrays are not pointers. Pointers are not arrays. Never have been, never
will be. That's a design decision too. If you don't like it, the most
sensible thing you can do is find a different language, because this is
basic stuff.

The presence or absence of bounds-checking is not a language issue, but an
implementation decision. If you want to put bounds-checking into a C
implementation, that's your choice, provided that the implementation
correctly translates correct programs. But don't expect to be able to force
your choice onto other implementors.

This is very, very simple. So the question is: do you *want* to understand?
If so, we'll help.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
.



Relevant Pages

  • Re: Which is better - a char type or a string of length one?
    ... indexing bits from the left or from the right and are you using these ... So strings and integers share the same property that index and slice ... On arrays of type T (although the language uses variants), ... A single-element slice of an array can be achieved with a single index ...
    (comp.lang.misc)
  • Re: When the goin gets tough! (Was Re: DEFCON 16 and Hacking OpenVMS ** 8.3 Patch available **)
    ... >>>>> simple truth is very few people have bothered looking at VMS because ... >>>>> still we see really dumb bugs popping up in some of the most popular ... checking as an inherenty part of the language, ... Strings are well treated in the language and null is a perfectly ...
    (comp.os.vms)
  • Re: Array difference
    ... is there any logical reason why the language doesn't ... but they plan on having a syntax like this. ... use the initialization syntax for the String array. ... Which declares that the method accepts a variable number of strings. ...
    (comp.lang.java.programmer)
  • Re: ruby course confusion
    ... Write a function find_it that takes an array of strings and a block. ... The block should take two parameters and return a boolean value. ... A method in one language is a function in another is a procedure in a third and doesn't even exist as a concept in a fourth language. ...
    (comp.lang.ruby)
  • Re: Query string before parsing
    ... which PHP does not handle. ... PHP has a precedent for introducing breaking changes to the language. ... This convention is a little hairy for forms that may have zero, one, or many checkboxes checked, as the handler needs to check whether the form value is a string or an array of strings, but it'd work and PHP has tools for doing that. ...
    (comp.lang.php)