jacob navia said:
Richard Heathfield a écrit :
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.
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.
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.
Of course. Only "conscious design decisions", like trigraphs...
Right.
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.
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.
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.
Your utter inability to understand simple logic does not make a good
advertisement for your product.
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.
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.
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.
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.
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.
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.
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.