Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

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

9 views
Skip to first unread message

shaanxxx

unread,
Dec 26, 2006, 8:25:25 AM12/26/06
to
I started programming with c. Lot of projects are being done in C++. We
have to move in THE C++.
I read around 3 - 4 books (including Faqs, stroustrup) on c++. What i
found in most of the book is that they criticize c language and c
programmer. And they silently run away from good feature of C.
They have sentence like , "you have to unlearn c to learn C++".

is it the end of C era ?
Stroustrup and writers of Faqs are gurus of technologies. These people
are commenting on C language.
should we believe them?
somewhere it is demoralizing for c programmer.

I just wanted to know what other people thinks on this .

jacob navia

unread,
Dec 26, 2006, 9:19:41 AM12/26/06
to
shaanxxx a écrit :

C++ started to eliminate C pitfalls but did not know when to stop,
in the way of complexity.

The problem with C is the lack of higher level constructs
that would allow a simpler and bug-free programming.

C++ started out as a preprocessor that compiled to C, that allowed
people to define classes, do object oriented programming, and
in general, as a way of eliminating the problems of C by
adding a new paradigm (object oriented programming) and
by making stricter type checking.

This led to multiple inheritance (one of the first mistakes), and
then templates, name spaces, and an incredible array of features
that make C++ a language so complex that has been almost impossible for
the compilers to follow.

As it stands now, there are maybe one or two implementations (EDG mainly
and maybe Comeau) that implement ALL of the language. All the other
compilers (gcc and microsoft included) implement some large subset of
the language, but not all of it.

People that understand the whole language are very few, since the
learning curve is steep, and unforgiving.

Obviously a language that started to "fix C" or to make a
"better C" is obviously in need of a reason, and 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.

C++ has added complexity without really having solved many of
the problems of C. Still you have to allocate/deallocate manually
the memory you want to use, without having an automatic garbage
collector, for instance.

In my opinion, some of the features of C++ are interesting, and
worthwhile, but too many of them make for a language that is just too
big.

jacob

dco...@connx.com

unread,
Dec 26, 2006, 10:12:27 AM12/26/06
to

Has COBOL gone away?
No. This kludgy 1950 language still clings on because it has a huge
installed base and actually solves some problems better than other
languages (e.g. look at some recent threads here involving currency
transactions which COBOL can handle with aplomb).

Languages do not go obsolete once they get popular. The problem domain
for C and C++ is not identical. For some projects C++ will be better
and for some projects C will be better.

Also important is the resources available for projects. If you have 50
good C programmers and 3 good C++ programmers, then most of your
projects will be C projects because that is what you can maintain.

People frequently prophecise about the demise of various popular
computer languages. They are always wrong.

Ben C

unread,
Dec 26, 2006, 12:30:19 PM12/26/06
to
On 2006-12-26, shaanxxx <shaa...@yahoo.com> wrote:
> I started programming with c. Lot of projects are being done in C++. We
> have to move in THE C++.
> I read around 3 - 4 books (including Faqs, stroustrup) on c++. What i
> found in most of the book is that they criticize c language and c
> programmer. And they silently run away from good feature of C.
> They have sentence like , "you have to unlearn c to learn C++".
>
> is it the end of C era ?

C is still very widely used, including for new projects.

Most people with any sense realize both that C++ does not necessarily
mean OOP, and that OOP is not a "silver bullet" anyway.

Out of people who know and understand quite well both languages, many
prefer C++ and many prefer C.

Most programmers have horror stories about bad code in both languages to
while away the long winter evenings.

> Stroustrup and writers of Faqs are gurus of technologies. These people
> are commenting on C language.
> should we believe them?

They're not exactly impartial gurus though.

Richard Heathfield

unread,
Dec 26, 2006, 3:54:31 PM12/26/06
to
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?

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

jacob navia

unread,
Dec 26, 2006, 6:04:41 PM12/26/06
to
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.

The most glaring bugs in C are:

1) Zero terminated strings. This is the source of countless problems,
because each access to a string implies an unbounded search for
the terminating zero, and becasue size information is not stored
explicitely in the string but must be reconstructed, so that
buffer overflows when copying those strings are almost inevitable.

Bounded strings can be written in C like this:

typedef struct tagString {
size_t length;
char *data;
unsigned flags;
} String;

Those are resizable strings. Non-resizable can be described
like this
typedef struct tagFixedString {
size_t length;
int flags;
char data[];
} FixedString;

I give this definitions to block people that say that
using other types of strings is impossible in C.
In the lcc-win32 compiler system, those strings are supported
in a special library.

2) Confusion between pointers and arrays. 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.

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.


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.

Another big problem is the error-prone malloc/free combination. We have
discussed this here several times. The solution is to use an automatic
software component (garbage collector) that manages the release of the
allocated memory. Lcc-win32 proposes this in its standard distribution.

Note that the objective here is not just to say what is wrong but to
propose solutions. That is why I mention lcc-win32, that is free anyway,
so I have no financial gain from it.

jacob

Malcolm

unread,
Dec 26, 2006, 6:09:21 PM12/26/06
to


"Richard Heathfield" <r...@see.sig.invalid> wrote in message
news:_I2dnUmQSrQwFgzY...@bt.com...


> 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?
>

It depends what you mean by bugs. C has a lot of weaknesses that are
inherent in a portable assembler: no special error-handling mechanism, no
garbage collection, to array bound guarding. None of this could be chnaged
with altering the design premises of the language, except maybe
error-handling, and even then no-one has found a good way that doesn't
involve hidden control paths.

There are a few other niggly things which could have been better. A few,
like the use of "char" for "byte" are simple details. Others, like the
syntax for multi-dimensional arrays, are a bit more deep-rooted. others,
like the typedef problem, are debateable. Most typedefs are a bad idea, but
there are a few cases where they actually help code maintainability.
Personally I would remove the keyword from the language if I was redesigning
C from scratch, but it is too late now, and that kind of knowledge only
comes from long experience.

Then there are some omissions. No distinction between functions which
perform IO and those which don't, no distinction between functions dependent
on platform-specific libraries and portable ones. I wouldn't describe these
exactly as "bugs".
--
www.personal.leeds.ac.uk/~bgy1mm
freeware games to download.

João Jerónimo

unread,
Dec 26, 2006, 7:06:31 PM12/26/06
to
Malcolm wrote:
> like the typedef problem, are debateable.

What's the typedef problem?
I don't like their syntax, but I think it's just a matter of taste...

> Most typedefs are a bad idea, but
> there are a few cases where they actually help code maintainability.
> Personally I would remove the keyword from the language if I was redesigning
> C from scratch, but it is too late now, and that kind of knowledge only
> comes from long experience.

I don't see the problem with a keyword that makes an alias to a type
(usually to a complex one)... If there wasn't typedefs, how would you
"export"[1] a type in a header?

[1] - It not really export, because exporting involves some kind of
linkage, isn't it?

JJ

Message has been deleted

Richard Heathfield

unread,
Dec 26, 2006, 7:22:18 PM12/26/06
to
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>



> 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.

> 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.

No bugs so far.

>
> 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.

> 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. And arrays are not pointers, so you can't get rid of "arrays
as pointers".

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

Why is that error-prone?

> 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. What could be easier? How is this
"error-prone"? You have never satisfactorily answered this.

> 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.

> 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 you have mentioned so far
constitutes a "bug" in C.

Ian Collins

unread,
Dec 26, 2006, 7:51:10 PM12/26/06
to
jacob navia wrote:
>
> C++ started to eliminate C pitfalls but did not know when to stop,
> in the way of complexity.
>
> The problem with C is the lack of higher level constructs
> that would allow a simpler and bug-free programming.
>
> C++ started out as a preprocessor that compiled to C, that allowed
> people to define classes, do object oriented programming, and
> in general, as a way of eliminating the problems of C by
> adding a new paradigm (object oriented programming) and
> by making stricter type checking.
>
OK so far.

> This led to multiple inheritance (one of the first mistakes), and
> then templates, name spaces, and an incredible array of features
> that make C++ a language so complex that has been almost impossible for
> the compilers to follow.
>

Debatable.

> As it stands now, there are maybe one or two implementations (EDG mainly
> and maybe Comeau) that implement ALL of the language. All the other
> compilers (gcc and microsoft included) implement some large subset of
> the language, but not all of it.
>

I know of at least one other, which makes for several more "complete"
C++ implementations than there are C99 ones.

> C++ has added complexity without really having solved many of
> the problems of C. Still you have to allocate/deallocate manually
> the memory you want to use, without having an automatic garbage
> collector, for instance.
>

The RAII (Resource Acquisition Is Initialisation) paradigm solves that
problem. This topic as been done to death both here and down the hall.

> In my opinion, some of the features of C++ are interesting, and
> worthwhile, but too many of them make for a language that is just too
> big.
>

You don't have to use them all, just the features that make for a better C.

--
Ian Collins.

newsm...@sbcglobal.net

unread,
Dec 26, 2006, 10:18:06 PM12/26/06
to

Just as poets find new and inventive ways to make antiquated languages sing with beauty,
so can a programmer by sticking with a language as elegant as C.

A good friend of mine had a BASH script he used which would run on average over 20 minutes.

As a programming practice in C (to freshen my skills) - remade the program

And it completed on average over 2 seconds....

From 20 minutes to 2 seconds... C's efficiency combined with the power left to the programmer

will always make it a favorite for years to come. It's just simply fun.

jacob navia

unread,
Dec 27, 2006, 1:17:46 AM12/27/06
to
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.

Customer: HEY! Your dammed program erased all my data files!
Programmer: Of course. You forgot to read the documentation page 2643
paragraph 76: If the cutomer doesn't check the dialog button
"Do not erase all my data files" in the menu item 8,submenu
26, the program will erase them.

IT IS NOT A BUG! IT IS A FEATURE!

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.


>
> <snip>
>
>
>>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

#include <stdio.h>
int array[2765];

void fn(int array[2765])
{
printf("sizeof array is: %d\n",sizeof(array));
}

int main(void)
{
fn(array);
}

This prints:
sizeof array is: 4

Ahhh. OF COURSE. Arrays "decay". This is a C only concept.
And this needs surely a lot of convoluted explanations
as the countless C-FAQ prove.

>
>> 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...

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.

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

> No bugs so far.
>

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

>
>>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. 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...)

>
>>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.

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!!!


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

Yeah, of course I can. Look at lcc-win32.

>
>>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.

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.

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

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.

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...

>
>>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?
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???


> 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...

> 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...
For all other people however, the reasoning is obvious.

>
>>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. It is still the programmer that allocates
memory. This is like saying that an automatic car doesn't let the driver
drive the car...

Nonsense

>
>>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. For programmers like you that never
make mistakes nothing is wrong. I am speaking for the other ones
like me that DO make mistakes.


> 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.

jacob navia

unread,
Dec 27, 2006, 1:48:16 AM12/27/06
to
Malcolm a écrit :

> "Richard Heathfield" <r...@see.sig.invalid> wrote in message
> news:_I2dnUmQSrQwFgzY...@bt.com...
>
>>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?
>>
>
> It depends what you mean by bugs. C has a lot of weaknesses that are
> inherent in a portable assembler: no special error-handling mechanism, no
> garbage collection, to array bound guarding. None of this could be chnaged
> with altering the design premises of the language, except maybe
> error-handling, and even then no-one has found a good way that doesn't
> involve hidden control paths.

With just one change to the language (operator overloading)
I have been able to develop an experimental compiler
that eliminates some of those problems.

The operator overloading allows lcc-win32 to use containers
(accessed with the array notation [ ] ) and with that have
arrays and strings that are bound checked.

Lcc-win32 offers a garbage collector in its standard distribution.

jacob navia

unread,
Dec 27, 2006, 1:51:07 AM12/27/06
to
Richard Heathfield a écrit :

> 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.

This is precisely what I do not accept.

Why being blind to the flaws of the language?

"C, is MY language. Take it or leave it!!!"

?????

Why isn't possible to discuss the flaws of the language
without flame wars?

I remember the starting days of Unix, where EVERY
manual page had a BUGS section. Has this attitude got
lost in this "language nationalism" ???

jacob

Richard Heathfield

unread,
Dec 27, 2006, 3:37:06 AM12/27/06
to
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

unread,
Dec 27, 2006, 3:46:34 AM12/27/06
to
jacob navia said:

> Richard Heathfield a écrit :
>> 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.
>
> This is precisely what I do not accept.
>
> Why being blind to the flaws of the language?

C isn't perfect (for one thing, it's grown too big). But I specifically mean
that when ***YOU***, Jacob Navia, start talking about bugs in the language,
we know it really means that you're going to bang on about your
implementation's useless non-portable mods that *you* think of as
improvements to what *you* think of as bugs in C.

> "C, is MY language. Take it or leave it!!!"

No, C is not your language to change as you please without consequences. C
is defined by ISO. If you want to change the language, talk to ISO.

> ?????
>
> Why isn't possible to discuss the flaws of the language
> without flame wars?

It is, but you don't seem to understand what the real flaws are.

>
> I remember the starting days of Unix, where EVERY
> manual page had a BUGS section. Has this attitude got
> lost in this "language nationalism" ???

No, not at all. But what you think are bugs are not in fact bugs. Why not
track down the real bugs instead?

CBFalconer

unread,
Dec 27, 2006, 5:00:26 AM12/27/06
to
jacob navia wrote:
> Richard Heathfield a écrit :
>> jacob navia said:
>>
... snip ...

>>
>>> 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.
>
> Customer: HEY! Your dammed program erased all my data files!
> Programmer: Of course. You forgot to read the documentation page
> 2643 paragraph 76: If the cutomer doesn't check the
> dialog button "Do not erase all my data files" in the
> menu item 8,submenu 26, the program will erase them.
>
> IT IS NOT A BUG! IT IS A FEATURE!
>
> 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.

You are welcome to use Ada and/or Pascal. This is virtually
guaranteed to avoid the above scenario. Not completely
guaranteed. Simply renaming ISO10206 to be C0x would do the whole
job. However it would break existing code.

>
... big snip ...


>
> 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...

Funny thing, my hashlib subsystem, written in purely standard C,
routinely controls millions of allocations without any known memory
leaks. It may have something to do with being systematic.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>


Malcolm

unread,
Dec 27, 2006, 7:44:49 AM12/27/06
to
"João Jerónimo" <j_j_...@yahoo.com.br> wrote in message

> Malcolm wrote:
>> like the typedef problem, are debateable.
>
> What's the typedef problem?
> I don't like their syntax, but I think it's just a matter of taste...
>
Bool breaks libraries.

That, in a nutshell, is the typedef problem. The ability to define aliases
for basic types makes code unreadable, and forces all code to use a
particular convention, making it difficult to integrate functions from two
sources.

Typedefing structs is a bit different. Here you are creating a compund type.

Richard Heathfield

unread,
Dec 27, 2006, 7:56:46 AM12/27/06
to
Malcolm said:

<snip>



> Typedefing structs is a bit different. Here you are creating a compund
> type.

...which has nothing to do with the typedef. The typedef doesn't create a
compound type. It merely creates a synonym for an existing type.

João Jerónimo

unread,
Dec 27, 2006, 12:30:45 AM12/27/06
to
Richard Heathfield wrote:
>> Typedefing structs is a bit different. Here you are creating a compund
>> type.
>
> ...which has nothing to do with the typedef. The typedef doesn't create a
> compound type. It merely creates a synonym for an existing type.

Yes, but it makes the use of compound types much simples, exactly
because of the alias...

JJ

João Jerónimo

unread,
Dec 27, 2006, 12:37:07 AM12/27/06
to
Malcolm wrote:
>>> like the typedef problem, are debateable.
>> What's the typedef problem?
>> I don't like their syntax, but I think it's just a matter of taste...
>>
> Bool breaks libraries.
>
> That, in a nutshell, is the typedef problem. The ability to define aliases
> for basic types makes code unreadable, and forces all code to use a
> particular convention, making it difficult to integrate functions from two
> sources.

That would be solved if C had some more precise types...
Instead of relying on "at least x bits" types, C should have defined
types with 8 bits, types with 16 bits and types with 32 bits...
This was difficult in the time when C was designed, because of the
diversity of architectures at the time (I think there were
bit-addressable machines, right?)...
But now "byte" is a synonym of "octet", right? What's the problem with that?

JJ

Richard Heathfield

unread,
Dec 27, 2006, 10:43:27 AM12/27/06
to
João Jerónimo said:

> Malcolm wrote:
>>>> like the typedef problem, are debateable.
>>> What's the typedef problem?
>>> I don't like their syntax, but I think it's just a matter of taste...
>>>
>> Bool breaks libraries.
>>
>> That, in a nutshell, is the typedef problem. The ability to define
>> aliases for basic types makes code unreadable, and forces all code to use
>> a particular convention, making it difficult to integrate functions from
>> two sources.
>
> That would be solved if C had some more precise types...

Why?

> Instead of relying on "at least x bits" types, C should have defined
> types with 8 bits, types with 16 bits and types with 32 bits...

Why?

> This was difficult in the time when C was designed, because of the
> diversity of architectures at the time (I think there were
> bit-addressable machines, right?)...
> But now "byte" is a synonym of "octet", right?

Wrong. Numerous counter-examples exist.

jacob navia

unread,
Dec 27, 2006, 12:16:51 PM12/27/06
to
Richard Heathfield a écrit :

> jacob navia said:
>
>
>>Richard Heathfield a écrit :
>>
>>>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.
>>
>>This is precisely what I do not accept.
>>
>>Why being blind to the flaws of the language?
>
>
> C isn't perfect (for one thing, it's grown too big). But I specifically mean
> that when ***YOU***, Jacob Navia, start talking about bugs in the language,
> we know it really means that you're going to bang on about your
> implementation's useless non-portable mods that *you* think of as
> improvements to what *you* think of as bugs in C.
>

Of course when *YOU* speak you do not do it for yourself but in
the name of all people that use C, all reasonable people, etc.

I know that when *I* speak I speak for myself.

And your point was?


Your opinion about lcc-win32 is second hand anyway since you
never use it. Your discussion so far presents no arguments
but "C strings are a design decision". So what? I know that.

I am just saying that they were a BAD design decision.

The same as with the example I wrote about arrays.

The evaluation of the expression

array

in the example, evaluates to a pointer, not to an array even
if the object is an array.

When I write
fn(array);

this "array" identifier evaluates to a pointer.

When I write

struct tagFoo {
int array[2756];
};

struct tagFoo array;

And I write later in some function:

fn(array);

The structure is passed by value. Not so for arrays.

This is (of course) a design decision. It is just
a very bad idea. ALL size information about the
array is lost.

But I know that you will throw some words to deny this, as you
have done in your previous messages, but it will not help you. This are
just FACTS.

jacob navia

unread,
Dec 27, 2006, 12:33:35 PM12/27/06
to
Richard Heathfield a écrit :

> 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.
>

I am not even talking about abuse. I am talking about
1) Error prone unbounded memory scans.
2) Inefficient scanning AGAIN and AGAIN the whole string
to know the length.
3) Memory overflows when copying.

Say, you have a buffer of 80 chars and you want to copy
a string into it. You have to scan the whole string first
to see if it fits!

OR

At each character you have to test if it fits
or you have reached the terminating zero.

Inefficient.

>
>>>>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
>

> The ignorance of
> the newbie is not the best yardstick for whether language features are a
> good idea or not.
>

Excuse me but not only newbies. Nobody cares to understand this
crazy "decay", and the other sophistications of when arrays are
arrays and when arrays are just pointers, so everybody
but the very few language experts says:

Arrays do not exist in C, only pointers, since arrays do not
survive function boundaries.

My example proves that it is impossible to pass array
size information to a function but you have to pass
it separatedly...

>
>>Ahhh. OF COURSE. Arrays "decay". This is a C only concept.
>
>
> Not true. It's also true, for example, in C++.
>

This was inherited from C, and you know that. They realized already
that this "array decaying" wasn't very good and developed a whole
new set of arrays. They had to anyway.

>
>>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 yes. All is OK, very simple. Then tell me:

How do you pass the array size information to a function
that will operate in an array?

You must pass it separatedly isn't it?

>
>>>> 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.
>>>
>>

Exactly. "It isn't always "conveyed" " as you say. I wasn't saying
anything else. That is the bug precisely. It is impossible
to pass that information to a function and use an array as
an object and not as a pointer!

>
> The expression's value is passed. Before that value is passed, it has to be
> calculated.

GREAT!

I did n,ot knew that. Really new stuff here :-)

> 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.

Well this is precisely the bug. Why when I define

struct tagArray { int array[2765];};

struct tagArray array;

Now, when I write

fn(array);

no "decaying" happens. Ahh, great. At least *some* things work!


>
>>>No bugs so far.
>>>
>>
>>Of course. Only "conscious design decisions", like trigraphs...
>
>
> Right.
>

Yes, another one of this FEATURES...

>
>>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.
>

Ahh, and all those packages like "Purify" and all those malloc/free
debuggers are sold by the thousands because.... well, because people
are lazy and stupid and do not follow your propositions obviously.


>
>
>>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.
>

Obvious. Multi-threading is not good for malloc/free then... instead of
getting rid of multi-threading let's get rid of malloc/free!

More and more applications are designed with multi-threading in mind.
Even the hardware is now multi-threaded with several "cores".

But let's keep living in the past...

Richard Heathfield

unread,
Dec 27, 2006, 1:06:31 PM12/27/06
to
jacob navia said:

<snip>


>
> Of course when *YOU* speak you do not do it for yourself but in
> the name of all people that use C, all reasonable people, etc.

No, I speak for myself, just as you do.

> I know that when *I* speak I speak for myself.
>
> And your point was?

Just beyond your grasp, it appears.

> Your opinion about lcc-win32 is second hand anyway since you
> never use it.

Yes. My opinion about lcc-win32 has been formed almost entirely from your
articles, so perhaps it would be wiser for you to avoid any temptation to
go into marketing.

> Your discussion so far presents no arguments
> but "C strings are a design decision". So what? I know that.

Then they can hardly constitute a bug. You might not like them; you might
think they're a bad idea; you might even think they constitute a blemish in
the language design - but to call them a "bug" is to misuse the term.

> I am just saying that they were a BAD design decision.

Fine, you're entitled to that opinion. I would even go so far as to say that
I don't entirely disagree with it.

> The same as with the example I wrote about arrays.
>
> The evaluation of the expression
>
> array
>
> in the example, evaluates to a pointer, not to an array even
> if the object is an array.

Correct.

> When I write
> fn(array);
>
> this "array" identifier evaluates to a pointer.

The expression has pointer type, yes.

> When I write
>
> struct tagFoo {
> int array[2756];
> };
>
> struct tagFoo array;
>
> And I write later in some function:
>
> fn(array);
>
> The structure is passed by value.

Correct.

> Not so for arrays.

The array isn't passed *at all*, so how can it be passed by value?

> This is (of course) a design decision. It is just
> a very bad idea. ALL size information about the
> array is lost.

No, it's not. The size information is retained. It is simply that the
information is not *conveyed* to a called function (unless you convey that
information yourself via, say, another argument to the function, and write
the function in such a way that it can receive this information). And why
should it? You're not, after all, passing an array. You're passing a
pointer.

> But I know that you will throw some words to deny this, as you
> have done in your previous messages, but it will not help you. This are
> just FACTS.

So you claim.

Richard Heathfield

unread,
Dec 27, 2006, 1:37:57 PM12/27/06
to
jacob navia said:

> Richard Heathfield a écrit :
>> 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.
>>
>
> I am not even talking about abuse. I am talking about
> 1) Error prone unbounded memory scans.

If you don't bound the scan, that's your problem, not C's problem. C
explicitly says that you're not supposed to do that. If you do it anyway,
the behaviour is undefined. So - Don't Do That.

> 2) Inefficient scanning AGAIN and AGAIN the whole string
> to know the length.

If you need to know the length often enough, store it. If you don't, why
bother?

> 3) Memory overflows when copying.

If you don't provide sufficient storage for the target of a copy, that's
your problem, not C's problem. C explicitly says that you're not supposed
to do that. If you do it anyway, the behaviour is undefined. So - Don't Do
That.

> Say, you have a buffer of 80 chars and you want to copy
> a string into it. You have to scan the whole string first
> to see if it fits!

When you built the string in the first place, you knew its length (if you
did it properly). Don't forget.

> OR
>
> At each character you have to test if it fits
> or you have reached the terminating zero.
>
> Inefficient.

If this is truly the program's bottleneck, which it almost certainly isn't,
then consider caching the length and using memcpy, or simply use a
third-party string library if you prefer. C's flexibility allows you to do
this, which is a Good Thing, yes?

>>>>>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
>>
>> The ignorance of
>> the newbie is not the best yardstick for whether language features are a
>> good idea or not.
>>
>
> Excuse me but not only newbies.

Okay, I will accept that we should also include amongst the ignorant those
who are unwilling to learn the language properly before using it.

> Nobody cares to understand this
> crazy "decay",

Here are two dozen counterexamples: I understand it. Chris Torek understands
it. Dik Winter understands it. Dan Pop understands it. Kaz Kylheku
understands it. Dennis Ritchie understands it. Brian Kernighan understands
it. Ken Thompson understands it. P J Plauger understands it. Stefan Wilms
understands it. Lawrence Kirby understands it. Keith Thompson understands
it. Dann Corbit understands it. Ben Pfaff understands it. Peter Seebach
understands it. Doug Gwyn understands it. Eric Sosman understands it. Dave
Thompson understands it. Chuck Falconer understands it. Steve Summit
understands it. Richard Bos understands it. Mark McIntyre understands it.
Christian Bau understands it. Clive Feather understands it.

And I have listed only a tiny fraction of those people who understand the
"decay" under discussion. So "nobody" is a bit of an exaggeration, isn't
it?

> and the other sophistications of when arrays are
> arrays and when arrays are just pointers, so everybody
> but the very few language experts says:

Arrays are always arrays. Pointers are always pointers. The name of an
array, however, is converted into a pointer to the array's first element
when used in an expression that is not the operand of sizeof or the &
operator.

> Arrays do not exist in C, only pointers, since arrays do not
> survive function boundaries.

Arrays survive function boundaries just fine.

#include <stdio.h>

int main(void)
{
char s[] = "Now is the time to party.";
puts(s); /* function boundary */
printf("%lu\n", (unsigned long)sizeof s); /* prints 26 - the
array has survived! */
return 0;
}

> My example proves that it is impossible to pass array
> size information to a function but you have to pass
> it separatedly...

Passing it separately still counts as passing it, so how is it impossible to
pass array size information to a function?

>>>Ahhh. OF COURSE. Arrays "decay". This is a C only concept.
>>
>>
>> Not true. It's also true, for example, in C++.
>>
>
> This was inherited from C, and you know that.

Had you known that, you would not have made your incorrect claim - or do you
deliberately make incorrect claims?

<snip>

>>>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 yes. All is OK, very simple.

Good, so what's your problem?

> Then tell me:
>
> How do you pass the array size information to a function
> that will operate in an array?

See fgets for an example.

> You must pass it separatedly isn't it?

Yes; you can't pass it *with* the array because you can't pass the array,
because C is pass-by-value and evaluating an array yields a pointer.

>>>>> 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.
>>>>
>>>
>
> Exactly. "It isn't always "conveyed" " as you say. I wasn't saying
> anything else.

Yes, you were. You said the size information is destroyed. You were wrong.
It is not destroyed at all.

> That is the bug precisely.

No, it's not a bug. This was a conscious design choice by dmr. You might
think it was a poor choice. You might even think it is a blemish on the
language. But to call it a bug is to misuse the term.

> It is impossible
> to pass that information to a function and use an array as
> an object and not as a pointer!

Yes, well done - you can't pass an array to a function. Do you understand
that now? (Well, actually you can, but only as a subobject within an
aggregate type such as a struct or union.)

>> The expression's value is passed. Before that value is passed, it has to
>> be calculated.
>
> GREAT!
>
> I did n,ot knew that. Really new stuff here :-)

It figures. It might be a good idea for you to learn the language before you
start making sweeping criticisms of it.

>> 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.
>
> Well this is precisely the bug.

No, it's not a bug. It's a deliberate design decision that you don't like.

> Why when I define
>
> struct tagArray { int array[2765];};
>
> struct tagArray array;
>
> Now, when I write
>
> fn(array);
>
> no "decaying" happens.

Correct. Whether that's a good thing or a bad thing is a matter for debate,
but you are at least correct for a change.

> Ahh, great. At least *some* things work!

The whole language works.

>>>>No bugs so far.
>>>
>>>Of course. Only "conscious design decisions", like trigraphs...
>>
>> Right.
>
> Yes, another one of this FEATURES...

Yes. And for the record, trigraphs make perfect sense in some environments.
If you don't like them, don't use them.

>>>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.
>
> Ahh, and all those packages like "Purify" and all those malloc/free
> debuggers are sold by the thousands because.... well, because people
> are lazy and stupid and do not follow your propositions obviously.

That's one way to track down such bugs, albeit a rather expensive way to
deal with a fairly simple problem. I do not accept that those who use
Purify are lazy or stupid, although I do not use it myself.


>>>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.
>>
>
> Obvious. Multi-threading is not good for malloc/free then...

You have not demonstrated that.

> instead of
> getting rid of multi-threading let's get rid of malloc/free!

You have not demonstrated that this is a wise idea.

> More and more applications are designed with multi-threading in mind.

That doesn't mean multi-threading is necessarily a wise idea. Indeed, in
most cases where I've encountered it, it was a very silly idea. (That does
not mean that multi-threading is a silly idea. It only means precisely what
it says.)

> Even the hardware is now multi-threaded with several "cores".
>
> But let's keep living in the past...

I'd rather live with the facts. So far, you haven't presented any that would
convince me that you know what you're talking about.

FreeRTOS.org

unread,
Dec 27, 2006, 1:36:40 PM12/27/06
to

"shaanxxx" <shaa...@yahoo.com> wrote in message
news:1167139525.7...@73g2000cwn.googlegroups.com...

>I started programming with c. Lot of projects are being done in C++. We
> have to move in THE C++.
> I read around 3 - 4 books (including Faqs, stroustrup) on c++. What i
> found in most of the book is that they criticize c language and c
> programmer. And they silently run away from good feature of C.
> They have sentence like , "you have to unlearn c to learn C++".
>
> is it the end of C era ?
> Stroustrup and writers of Faqs are gurus of technologies. These people
> are commenting on C language.
> should we believe them?
> somewhere it is demoralizing for c programmer.
>
> I just wanted to know what other people thinks on this .


Like most things - choose the best tool for the job and be pragmatic.
Sometimes assembler, sometimes C, sometimes C++ (sometimes ADA, etc.). Each
has their place.

Working in the embedded field I have completed many *object based* projects
in C for which I would never consider using C++. I have also completed
projects in C++ I would not consider to be appropriate to tackle in C
considering C++ was available as an option.

I have encountered C++ Nazis who know ever last detail of the C++ spec and
consider you antiquated/foolish if you use C. I like watching them fall
flat on their arses when they try and write an embedded project and their
code does not even compile ;-) Naturally it is "the compilers fault"
because it does not correctly implement the standard - like anybody thought
it would.

Regards,
Richard.

+ http://www.FreeRTOS.org
+ http://www.SafeRTOS.com
for Cortex-M3, ARM7, ARM9, HCS12, H8S, MSP430
Microblaze, Coldfire, AVR, x86, 8051, PIC24 & dsPIC


Charlton Wilbur

unread,
Dec 27, 2006, 2:04:09 PM12/27/06
to
>>>>> "jn" == jacob navia <ja...@jacob.remcomp.fr> writes:

jn> Your opinion about lcc-win32 is second hand anyway since you
jn> never use it. Your discussion so far presents no arguments but
jn> "C strings are a design decision". So what? I know that.

jn> I am just saying that they were a BAD design decision.

You know, when Bjarne Stroustrup decided he didn't like some of the
limitations of C, he designed C++.

When Brad Cox didn't like some of the limitations of C, he designed
Objective-C.

The problem here is not that you see design flaws in C. The problem
is that you believe, in contravention of all evidence, that you can
singlehandedly redesign C *and still call it C*.

C is the language defined by K&R, K&R2, and the C89/90 and C99 standards.

If you want a language remarkably like C, but with length-counted
strings and garbage collection, hey, more power to you! It's likely
to be a fine language, and possibly more useful, more efficient, and
more resilient than C. But unless it conforms to the C standards, it
isn't C.

So why not design the language you really want, and call it something
else?

Charlton

--
Charlton Wilbur
cwi...@chromatico.net

Randy Howard

unread,
Dec 27, 2006, 4:29:55 PM12/27/06
to
On Wed, 27 Dec 2006 00:17:46 -0600, jacob navia wrote
(in article <45921009$0$5083$ba4a...@news.orange.fr>):
> Richard Heathfield a écrit :

>>> 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.
>
> Customer: HEY! Your dammed program erased all my data files!
> Programmer: Of course. You forgot to read the documentation page 2643
> paragraph 76: If the cutomer doesn't check the dialog button
> "Do not erase all my data files" in the menu item 8,submenu
> 26, the program will erase them.
>
> IT IS NOT A BUG! IT IS A FEATURE!
>
> 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.

Strawman. These are not equivalent at all. C gives you something
analogous to a Machete. Apparently, you would prefer a machete that is
never sharpened, only available with a special license, and has a hard
clear plastic cover such that it can't cut anything without melting it
off first with a blowtorch.

Some things, in order to serve their design purpose, are inherently
dangerous. That means, the people that use them must be intelligent,
competent in their employment, and not careless if they intend to
survive the usage unharmed. Same is true of cars, airplanes,
chainsaws, even toothpicks.

If you want a super-handholding, ultra-safe language, they are out
there. C is not for amateurs, or those not willing or able to spend
the time to learn where the sharp spots are.

>>> 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
>
> #include <stdio.h>
> int array[2765];
>
> void fn(int array[2765])
> {
> printf("sizeof array is: %d\n",sizeof(array));
> }
>
> int main(void)
> {
> fn(array);
> }
>
> This prints:
> sizeof array is: 4
>
> Ahhh. OF COURSE. Arrays "decay". This is a C only concept.
> And this needs surely a lot of convoluted explanations
> as the countless C-FAQ prove.

If you want to fly an airplane, you must first learn how to fly, lest
you crash and die. If you want to program in C, you must first learn
the language, for basically the same reason.

>> No bugs so far.
>>
>
> Of course. Only "conscious design decisions", like trigraphs...

They served a purpose at the time they were designed in. If you're too
young to understand why, that's not a reason to pretend they were never
needed.

>>> 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.

No. It's far more simpler. If you have a bug in a program that is due
to faulty logic, algorithms, or even a typo, that's a bug, and C can
have them quite often. You can be a very competent programmer and very
knowledgeable of C and still make mistakes. Perfection is not often
attained.

OTOH, if you have a bug due to you as a programmer directly violating
the rules of the language itself, that is not the fault of the
language. That is not knowing what you're doing.

> 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...)

Did you actually believe Dan? rofl

>>> 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.
>
> 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!!!

You give navia-C programmers a choice. You do not give standard C
programmers a choice. IIRC, the bstring library (name??) written by
Hsieh gives much the same (if not better) functionality, but without
requiring the compiler to do nonstandard things to get there. A /far/
better approach imo.

>>> 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.
>
> 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.
>
> If I tell you to add thousands of digits thousands of times
> you WILL make a mistake, even if you are an expert.

That same "brain circuitry" makes mistakes in super-safe,
super-handholding, super-slow languages too. In fact, waiting on
programs written in them to simply complete has been known to cause
programmers to fall asleep too often. 9 out of 10 doctors agree.

> 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.

The question is, is the performance and/or memory footprint advantages
of the C approach worth a little bit of extra debugging to achieve a
satisfactory result, or would you rather do it some other way, and take
the tradeoffs implied? That's why there are other languages to choose
from. It's also why you can buy a hybrid car with 15 different airbags
and roll bars, or you can buy a Ferrari F1 car. They achieve different
things, and require a dramatically different amount of skill to use
them effectively.

> 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...

I've been writing multi-threaded programs (not in standard C of course,
since it doesn't have them) in both large and small-scale applications
for many years. malloc/free work fine. Did you have a point
applicable to standard C?


>> 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?
> 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???

You first must be knowledgeable of the language, knowledgeable of the
code, have a good design, follow good practices, good documentation,
and have some form of suitable verification, code review and test
procedures. hint: I wouldn't expect someone with very little real
world application development experience to get this right. It is
hard. Just about anything worth doing is difficult.

>> 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...

If you want an /easy/ language, you are in the wrong place. Not
everything /easy/ is /correct/ for the job at hand. There are places
where other languages have merit, and there are places where C has
merit, and it is not important that any one language be good at them
all.

>> 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...
> For all other people however, the reasoning is obvious.

Actually, the "reasoning" seems to be "If I have trouble with it, then
everyone must have trouble with it. Anyone that doesn't have trouble
with it ticks me off."

>> 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. It is still the programmer that allocates
> memory. This is like saying that an automatic car doesn't let the driver
> drive the car...
>
> Nonsense

Actually, if you've driven both manual and automatic transmissions
(well), then you wouldn't choose that analogy at all, as it does not
help your argument.

>>> 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. For programmers like you that never
> make mistakes nothing is wrong. I am speaking for the other ones
> like me that DO make mistakes.

I know of no language that will protect a mistake-prone programmer from
themselves. NONE. With or without garbage collection assistance, or
pointers removed, or arrays conveying extra information across function
calls, you will still make mistakes. Just different ones. What you
will not get though, is better performance and/or a smaller footprint
in all but the most trivial of examples. It's an implementation
decision. I haven't seen anyone say that you should use C for all
problems, and more importantly, for programmers of all skillsets.

>> 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.

Ironically, I couldn't agree more.

--
Randy Howard (2reply remove FOOBAR)
"The power of accurate observation is called cynicism by those
who have not got it." - George Bernard Shaw

Randy Howard

unread,
Dec 27, 2006, 4:47:33 PM12/27/06
to
On Wed, 27 Dec 2006 11:33:35 -0600, jacob navia wrote
(in article <4592ae70$0$27377$ba4a...@news.orange.fr>):

> Richard Heathfield a écrit :
>> 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.
>>
>
> I am not even talking about abuse. I am talking about
> 1) Error prone unbounded memory scans.

If you as a programmer don't make sure your strings are properly
formed, you will have problems. If your algorithm is not properly
formed, you will also have problems. Why is this confusing?

> 2) Inefficient scanning AGAIN and AGAIN the whole string
> to know the length.

That's a design flaw. If you have a program where that time is an
issue, design your code to mitigate the problem. This is not
difficult.

> 3) Memory overflows when copying.

Only when not copying properly. Are there artifacts in the standard
library that make this a dangerous path for the uninitiated?
Absolutely. Are they impossible to avoid? Not at all.

> Say, you have a buffer of 80 chars and you want to copy
> a string into it. You have to scan the whole string first
> to see if it fits!

No, you do not /have/ to do that. You /may/ need to do that if you
didn't write code to solve the problem before you go there.

> OR
>
> At each character you have to test if it fits
> or you have reached the terminating zero.
>
> Inefficient.

Yes, the methods you propose to use are inefficient. Why is that not
surprising me?

>>>>> 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
>>
>> The ignorance of
>> the newbie is not the best yardstick for whether language features are a
>> good idea or not.
>
> Excuse me but not only newbies. Nobody cares to understand this
> crazy "decay", and the other sophistications of when arrays are
> arrays and when arrays are just pointers, so everybody
> but the very few language experts says:
>
> Arrays do not exist in C, only pointers, since arrays do not
> survive function boundaries.
>
> My example proves that it is impossible to pass array
> size information to a function but you have to pass
> it separatedly...

You are confused. If you can pass it to the function, /in any way/
then it is not impossible to pass it. You contradict yourself. I know
what you meant though. You can't pass it the way you want to pass it.
Tough. Get used to it, or find a language that works the way you like.
Just don't call that other language "C", or try to convince people
comfortable with C that your way is the only way and you won't have
anything to argue about.

> Exactly. "It isn't always "conveyed" " as you say. I wasn't saying
> anything else. That is the bug precisely. It is impossible
> to pass that information to a function and use an array as
> an object and not as a pointer!

You use the word "impossible" far too often, and far too improperly.

If it were impossible to handle arrays in C, the language would have
died before you were born. Clearly the problem has known solutions.

>> I would claim no such thing. I would, however, claim that tracking such
>> things down is not nearly as difficult as you imagine.
>
> Ahh, and all those packages like "Purify" and all those malloc/free
> debuggers are sold by the thousands because.... well, because people
> are lazy and stupid and do not follow your propositions obviously.

It's crazy just how close to right you landed on that one. Even a
stopped clock is right twice a day....

>>> 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.

Here I have to disagree with Richard. It does offer real benefits in
some problem domains. That they may not be encountered often in
Richard's travels I won't dispute. But, such cases do exist. There
are ways other than threads to solve those problems also, but typically
they are even more difficult. Multithreaded programming is not /easy/,
therefore it is not surprising that Navia doesn't like it. He has
repeatedly come down on the side of "easy" over "efficient".

> Obvious. Multi-threading is not good for malloc/free then...

False. It works fine when correctly done.

> instead of getting rid of multi-threading let's get rid of malloc/free!

There is no multi-threading to get rid of in the terms of this
discussion, since it is about C. The real C, not the pseudo-C you are
so fond of.

> More and more applications are designed with multi-threading in mind.

That is in fact the problem. "Designed with X in mind" is a sure
warning sign that X isn't correctly done at all. Luckily, more and
more applications are designed and built with working thread solutions.
"Designed with X in mind" typically means: "I heard about this thing X
and my sadly, my boss has too. He is worried about it impacting the
size of his empire. I spent 20 minutes googling for X, and wrote in
the Executive Summary of my design document that the design has X in
mind, so now everybody is happy, and I'll be long gone before anyone
figures out the difference."

Richard Heathfield

unread,
Dec 27, 2006, 4:58:36 PM12/27/06
to
Randy Howard said:

>> Richard Heathfield a écrit :

<snip>

>>> 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.
>
> Here I have to disagree with Richard. It does offer real benefits in
> some problem domains.

Sure, but they're fewer and further between than most people imagine. At
least, I almost invariably find that people who ask me for help with
multithreaded programs have misunderstood what multithreading is *for*.
They seem to think their programs will run quicker *per se* if they're
multithreaded, as if their computer, on encountering the multi-threaded
program, suddenly grows an extra CPU or something.

<snip>

> Multithreaded programming is not /easy/,

Right. As you are undoubtedly aware already, multithreading is for those who
can't figure out state machines - and state machines are for those who
can't figure out multithreading. :-)

<snip>

Randy Howard

unread,
Dec 27, 2006, 5:07:15 PM12/27/06
to
On Wed, 27 Dec 2006 15:58:36 -0600, Richard Heathfield wrote
(in article <at2dnae_McK...@bt.com>):

> Randy Howard said:
>
>>> Richard Heathfield a écrit :
>
> <snip>
>
>>>> 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.
>>
>> Here I have to disagree with Richard. It does offer real benefits in
>> some problem domains.
>
> Sure, but they're fewer and further between than most people imagine.

Absolutely. But when you do have a problem suitable for
multi-threading, they can and often do the job very well.

> At least, I almost invariably find that people who ask me for help with
> multithreaded programs have misunderstood what multithreading is *for*.

No doubt. Companies with names like "Intel" spew so much BS about
threading, it's hard to imagine that not being a problem.

> They seem to think their programs will run quicker *per se* if they're
> multithreaded, as if their computer, on encountering the multi-threaded
> program, suddenly grows an extra CPU or something.

The other misconception, which it /sounds/ like may apply to you given
the above, although I rather doubt it, is that threading can only help
in situations where you are CPU-bound. It is also quite helpful in
some i/o bound situations (i.e. server land), but not in the way most
people think. There are several large 'buckets' of problems which can
benefit from threading, and the contents of one bucket don't resemble
the contents of the next bucket much at all.

>> Multithreaded programming is not /easy/,
>
> Right. As you are undoubtedly aware already, multithreading is for those who
> can't figure out state machines - and state machines are for those who
> can't figure out multithreading. :-)

I'm not sure I agree with that in the literal sense, but I get the
humor in it nevertheless.

CBFalconer

unread,
Dec 27, 2006, 5:03:39 PM12/27/06
to
Richard Heathfield wrote:
> jacob navia said:
>> Richard Heathfield a écrit :
>>
... snip ...

>
> Okay, I will accept that we should also include amongst the
> ignorant those who are unwilling to learn the language properly
> before using it.
>
>> Nobody cares to understand this crazy "decay",
>
> Here are two dozen counterexamples: I understand it. Chris Torek
> understands it. Dik Winter understands it. Dan Pop understands it.
> Kaz Kylheku understands it. Dennis Ritchie understands it. Brian
> Kernighan understands it. Ken Thompson understands it. P J Plauger
> understands it. Stefan Wilms understands it. Lawrence Kirby
> understands it. Keith Thompson understands it. Dann Corbit
> understands it. Ben Pfaff understands it. Peter Seebach
> understands it. Doug Gwyn understands it. Eric Sosman understands
> it. Dave Thompson understands it. Chuck Falconer understands it.
> Steve Summit understands it. Richard Bos understands it. Mark
> McIntyre understands it. Christian Bau understands it. Clive
> Feather understands it.

Possibly better expressed as an linked list :-)
>
... snip ...


>
>> My example proves that it is impossible to pass array size
>> information to a function but you have to pass it separatedly...
>
> Passing it separately still counts as passing it, so how is it
> impossible to pass array size information to a function?

Which is just what strlcpy/cat do. They also provide a post-call
means of detecting that the passed size was insufficient, and of
deciding what that size needs to be.

char a[size];
size_t lgh;
...
if ((lgh = strlcpy(array, whatever, sizeof a)) >= sizeof a){
/* it got truncated */;
else /* everything fit */;

and the necessity of passing the available size tends to encourage
the programmer to supply that value, on pain of rejection at
compile time.

... large snip ...

Keith Thompson

unread,
Dec 27, 2006, 5:54:11 PM12/27/06
to

I hardly think that being able to refer to a type as "foo" rather than
"struct foo" makes compound types much simpler. And typedefs make
defining recursive types (structures with pointers to themselves)
*more* complicated.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

Richard Heathfield

unread,
Dec 27, 2006, 6:09:45 PM12/27/06
to
Keith Thompson said:

<snip>



> I hardly think that being able to refer to a type as "foo" rather than
> "struct foo" makes compound types much simpler.

Agreed.

> And typedefs make
> defining recursive types (structures with pointers to themselves)
> *more* complicated.

Not agreed. The process is no more complicated than without typedef. The
important thing to remember is that the type synonym isn't usable until the
type exists. The fact that you can "embed" the type definition within the
typedef is a mere distraction, and in any case is not compulsory. Nowadays,
I do this as follows:

struct node_
{
void *data;
struct node_ *left;
struct node_ *right;
};

typedef struct node_ node;

to separate out the two steps, making the whole process clearer. (Yes, I
know I could use the same name for the struct tag and the typedef, but I
choose not to do so, because I think it's a possible source of confusion
for the maintenance programmer.)

Mark McIntyre

unread,
Dec 27, 2006, 6:12:39 PM12/27/06
to
On Wed, 27 Dec 2006 21:58:36 +0000, in comp.lang.c , Richard
Heathfield <r...@see.sig.invalid> wrote:

>Randy Howard said:
>
>>> Richard Heathfield a écrit :
>

(randy wrote, commenting on Richard's assertion that multithreading is
of little benefit)


>
>> Here I have to disagree with Richard. It does offer real benefits in
>> some problem domains.

...
>[people] seem to think their programs will run quicker *per se* if they're
>multithreaded,

Consider that most modern computer systems have multiple processors -
graphics controllers, dedicated HDD controllers, dedicated network
controllers etc.

>as if their computer, on encountering the multi-threaded
>program, suddenly grows an extra CPU or something.

Many systems also have multi-cpu cores. Single threaded apps cannot
take full advantage of that, no matter how clever the compiler or OS
are.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan

Richard Heathfield

unread,
Dec 27, 2006, 6:19:06 PM12/27/06
to
Mark McIntyre said:

> On Wed, 27 Dec 2006 21:58:36 +0000, in comp.lang.c , Richard
> Heathfield <r...@see.sig.invalid> wrote:
>

<snip>

>>[people] seem to think their programs will run quicker *per se* if they're
>>multithreaded,
>
> Consider that most modern computer systems have multiple processors -
> graphics controllers, dedicated HDD controllers, dedicated network
> controllers etc.

Nevertheless, simply making your program multi-threaded will not mean that
it is guaranteed to run faster.

>>as if their computer, on encountering the multi-threaded
>>program, suddenly grows an extra CPU or something.
>
> Many systems also have multi-cpu cores. Single threaded apps cannot
> take full advantage of that, no matter how clever the compiler or OS
> are.

A user of a single-threaded program can nevertheless take at least *some*
advantage, because he can run that program on one CPU and some other
program on another.

But my main point is that multithreading is not a magic wand you can wave at
any problem. It can certainly be used effectively, but it can also be used
ineffectually, and can even be counter-productive.

Dik T. Winter

unread,
Dec 27, 2006, 7:05:42 PM12/27/06
to
In article <45921009$0$5083$ba4a...@news.orange.fr> jacob navia <ja...@jacob.remcomp.fr> writes:
> Richard Heathfield a écrit :
> > jacob navia said:
...

> >>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.

Perhaps. But the conclusion that it is impossible to do bound checking
is false. If a compiler decides to use fat pointers, bound checking *is*
possible.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/

August Karlstrom

unread,
Dec 27, 2006, 8:13:46 PM12/27/06
to
newsm...@sbcglobal.net skrev:
> A good friend of mine had a BASH script he used which would run on average over 20 minutes.
>
> As a programming practice in C (to freshen my skills) - remade the program
>
> And it completed on average over 2 seconds....
>
> From 20 minutes to 2 seconds... C's efficiency combined with the power left to the programmer

And what features specific to C enabled you to make the program that
much more efficient?


August

newsm...@sbcglobal.net

unread,
Dec 27, 2006, 9:13:38 PM12/27/06
to

1) My friend and I have noticed that working with arrays in C are much faster than anything we compile with any other language. The programming concepts are the same, but the implementation on systems make C run faster on average

(from our experience)

2) The built in library functions of bsearch and qsort work faster than using strings in C++ for doing much the same thing. (Obviously a lot faster then using BASH)


I must say that these are observations that we have seen. I'm not stating they're a universal experience, have
you had the same experience?

João Jerónimo

unread,
Dec 27, 2006, 11:29:13 PM12/27/06
to
Keith Thompson wrote:
>> Yes, but it makes the use of compound types much simples, exactly
>> because of the alias...
>
> I hardly think that being able to refer to a type as "foo" rather than
> "struct foo" makes compound types much simpler. And typedefs make
> defining recursive types (structures with pointers to themselves)
> *more* complicated.

I really shouldn't be discussing this kind of things with the little
experience I have...

Sorry!


Today I was for the first time trying to implement a linked list in C
and faced exactly this problem!
And then I started thinking about whether to abstract the structures
with typedefs or not!

JJ

João Jerónimo

unread,
Dec 27, 2006, 11:40:50 PM12/27/06
to
Richard Heathfield wrote:
>> And typedefs make
>> defining recursive types (structures with pointers to themselves)
>> *more* complicated.
>
> Not agreed. The process is no more complicated than without typedef. The
> important thing to remember is that the type synonym isn't usable until the
> type exists.

But on the other hand, a structure (in the structures namespace) can be
used before completely defined... It doesn't need to be defined, either!


In fact, I tried that now:
typedef struct garbage garb;

gcc doesn't complain if I try to create an object from this code...
If I try to access it before struct garbage exists it complains that it
doesn't know the size (because it needs to allocate space on the stack)...

JJ

João Jerónimo

unread,
Dec 27, 2006, 11:51:57 PM12/27/06
to
Richard Heathfield wrote:
>> That would be solved if C had some more precise types...
>> Instead of relying on "at least x bits" types, C should have defined
>> types with 8 bits, types with 16 bits and types with 32 bits...
>
> Why?

In my opinion (not very experienced, I admit), the types with imprecise
size aren't bad... Only there could *also* be the precise ones.

Remember that when programming in very low-level, one has sometimes to
adapt data structures to hardware-imposed patterns...


And typedefs allow working around this.

>> This was difficult in the time when C was designed, because of the
>> diversity of architectures at the time (I think there were
>> bit-addressable machines, right?)...
>> But now "byte" is a synonym of "octet", right?
>
> Wrong. Numerous counter-examples exist.

Can you give some of these examples?

JJ

Randy Howard

unread,
Dec 28, 2006, 12:28:09 AM12/28/06
to
On Wed, 27 Dec 2006 17:19:06 -0600, Richard Heathfield wrote
(in article <io2dnXTBtLu...@bt.com>):

> Mark McIntyre said:
>
>> On Wed, 27 Dec 2006 21:58:36 +0000, in comp.lang.c , Richard
>> Heathfield <r...@see.sig.invalid> wrote:
>>
> <snip>
>
>>> [people] seem to think their programs will run quicker *per se* if they're
>>> multithreaded,
>>
>> Consider that most modern computer systems have multiple processors -
>> graphics controllers, dedicated HDD controllers, dedicated network
>> controllers etc.
>
> Nevertheless, simply making your program multi-threaded will not mean that
> it is guaranteed to run faster.

This is generally true. Most people, especially when first exposed to
threads usually manage to make their program run much slower. Of
course, that is no more the fault of threads than programmers having
problems with pointers are C's fault. :-)

> A user of a single-threaded program can nevertheless take at least *some*
> advantage, because he can run that program on one CPU and some other
> program on another.

True, but that's only a seat-of-the-pants speedup, whether a single
application runs faster or not, the system as a whole feels faster.

> But my main point is that multithreading is not a magic wand you can wave at
> any problem. It can certainly be used effectively, but it can also be used
> ineffectually, and can even be counter-productive.

That's true of any programming methodology, language or even API.

jacob navia

unread,
Dec 28, 2006, 4:18:33 AM12/28/06
to
Randy Howard a écrit :

>
>>>No bugs so far.
>>>
>>
>>Of course. Only "conscious design decisions", like trigraphs...
>
>
> They served a purpose at the time they were designed in. If you're too
> young to understand why, that's not a reason to pretend they were never
> needed.
>

I am just saying they are not needed any more. Why they are here?
Because a Danish manufacturer had problems with '{' and other
letters of the C alphabet. In the horse trading that goes behind
the publications of international standards they got into the
standard that trigraphs would be there to save them.

Then, time passes, the manufacturer has disappeared since a long
time, and we are stuck with a nonsense construct!!!!

>
> OTOH, if you have a bug due to you as a programmer directly violating
> the rules of the language itself, that is not the fault of the
> language. That is not knowing what you're doing.
>

Ahh bugs are BAD BAD.

Great discovery. We are discussing how to avoid them if possible.
One of the ways to avoid them is to make things automatic
whenever possible so that the programmer has less to do, and less
possibilities of errors.

Why C is better than assembly?

Because the level of detail that you have to care about is less.

You just write:

c = a+b;

and you do not have to care about which register you use,
which address are b and c, etc etc.

If we have counted strings the length of the string is no longer
a problem you have to manage but the string library.

If you use the GC you do not care about free(). One problem
LESS to care about

jacob navia

unread,
Dec 28, 2006, 5:08:48 AM12/28/06
to
Randy Howard a écrit :

> On Wed, 27 Dec 2006 00:17:46 -0600, jacob navia wrote
> (in article <45921009$0$5083$ba4a...@news.orange.fr>):
>
>>Richard Heathfield a écrit :
>>
>>>>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.
>>
>>Customer: HEY! Your dammed program erased all my data files!
>>Programmer: Of course. You forgot to read the documentation page 2643
>> paragraph 76: If the cutomer doesn't check the dialog button
>> "Do not erase all my data files" in the menu item 8,submenu
>> 26, the program will erase them.
>>
>> IT IS NOT A BUG! IT IS A FEATURE!
>>
>>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.
>
>
> Strawman. These are not equivalent at all. C gives you something
> analogous to a Machete. Apparently, you would prefer a machete that is
> never sharpened, only available with a special license, and has a hard
> clear plastic cover such that it can't cut anything without melting it
> off first with a blowtorch.

To answer you in terms of your own analogy:

C gives you a machette without a HANDLE.
You can't use it without cutting yourself the hand.

I want to add a HANDLE to the machette i.e. a BLUNT
side where I can handle it without getting my blood in my
fingers...

jacob

Richard Heathfield

unread,
Dec 28, 2006, 5:11:39 AM12/28/06
to
João Jerónimo said:

> Richard Heathfield wrote:
>>> And typedefs make
>>> defining recursive types (structures with pointers to themselves)
>>> *more* complicated.
>>
>> Not agreed. The process is no more complicated than without typedef. The
>> important thing to remember is that the type synonym isn't usable until
>> the type exists.
>
> But on the other hand, a structure (in the structures namespace) can be
> used before completely defined... It doesn't need to be defined, either!

No, it can't be used before it is defined. But its *name* can be used in a
typedef, yes.

> In fact, I tried that now:
> typedef struct garbage garb;

Yes, that's legal.

> gcc doesn't complain if I try to create an object from this code...

When invoked in conforming mode, it must complain.

> If I try to access it before struct garbage exists it complains that it
> doesn't know the size (because it needs to allocate space on the stack)...

C doesn't require implementations to allocate space on any kind of "stack",
but the type must be complete before you can define an object of that type.

Richard Heathfield

unread,
Dec 28, 2006, 5:21:44 AM12/28/06
to
João Jerónimo said:

> Richard Heathfield wrote:
>>> That would be solved if C had some more precise types...
>>> Instead of relying on "at least x bits" types, C should have defined
>>> types with 8 bits, types with 16 bits and types with 32 bits...
>>
>> Why?
>
> In my opinion (not very experienced, I admit), the types with imprecise
> size aren't bad... Only there could *also* be the precise ones.

Fine, but eventually people will say "why does C have this
guaranteed-to-be-exactly-8-bits type? Nobody has used 8-bit bytes for
*decades*!" And we will not even have the excuse of "historical reasons",
since C started off *without* such a type.

> Remember that when programming in very low-level, one has sometimes to
> adapt data structures to hardware-imposed patterns...

...which is why C leaves the exact size of types up to the implementor.

> And typedefs allow working around this.

No, they just let you create a new name for an existing type.

>
>>> This was difficult in the time when C was designed, because of the
>>> diversity of architectures at the time (I think there were
>>> bit-addressable machines, right?)...
>>> But now "byte" is a synonym of "octet", right?
>>
>> Wrong. Numerous counter-examples exist.
>
> Can you give some of these examples?

I can give you one, because it's one that I have written C code for: the
Analog SHARC DSP (used in set-top boxes, e.g. DVD players, Web TV, that
sort of thing), which has 32-bit bytes. So sizeof(long), sizeof(short),
sizeof(int), and sizeof(char) are all the same: 1.

No doubt others here can tell you about other DSPs with 16- or 32-bit bytes.
They're hardly rare. Also, various dinosaurs have had very weird byte
sizes, e.g. 9, 36, and I believe there was once a 24 (BICBW).

All that C guarantees is that your bytes will be *at least* 8 bits wide, and
*exactly* CHAR_BIT bits wide, where the value of CHAR_BIT is set by the
implementation.

Richard Heathfield

unread,
Dec 28, 2006, 5:53:58 AM12/28/06
to
jacob navia said:

<snip>
>
> I am just saying [trigraphs] are not needed any more. Why they are here?


> Because a Danish manufacturer had problems with '{' and other
> letters of the C alphabet. In the horse trading that goes behind
> the publications of international standards they got into the
> standard that trigraphs would be there to save them.
>
> Then, time passes, the manufacturer has disappeared since a long
> time, and we are stuck with a nonsense construct!!!!

So you claim. Nonetheless, trigraphs remain useful even now in, say,
mainframe environments. But if you don't like trigraphs, don't use them.

<snip>

> Great discovery. We are discussing how to avoid them if possible.

> One of the ways to avoid [bugs] is to make things automatic


> whenever possible so that the programmer has less to do, and less
> possibilities of errors.

Quite so, but that automation comes at a cost (typically a performance
drop). So there's a trade-off here - you can automate some parts of your
program generation and reduce programmer time, or you can do it by hand and
reduce runtime. For people who want the former, there are already other
languages that cater for them. For people who want the latter, C caters for
them. If you change C so that it no longer caters for those people, they
will ignore the changes, and go on using the old C, because the old C meets
their needs better than the new C does.

> Why C is better than assembly?

Because it's portable. Duh.

<snip>

Richard Heathfield

unread,
Dec 28, 2006, 5:56:32 AM12/28/06
to
jacob navia said:

Your handle came off? Poor you.

> You can't use it without cutting yourself the hand.

Yes, he can. So can I. You're the one that's lost the handle.

> I want to add a HANDLE to the machette i.e. a BLUNT
> side where I can handle it without getting my blood in my
> fingers...

A machete with a blunt long edge is only 50% effective. It's *supposed* to
be sharp on both the long edges. And it's a lousy analogy anyway.

Mark McIntyre

unread,
Dec 28, 2006, 6:12:51 AM12/28/06
to
On Wed, 27 Dec 2006 23:19:06 +0000, in comp.lang.c , Richard
Heathfield <r...@see.sig.invalid> wrote:

>Mark McIntyre said:
>
>> On Wed, 27 Dec 2006 21:58:36 +0000, in comp.lang.c , Richard
>> Heathfield <r...@see.sig.invalid> wrote:
>>
><snip>
>
>>>[people] seem to think their programs will run quicker *per se* if they're
>>>multithreaded,
>>
>> Consider that most modern computer systems have multiple processors -
>> graphics controllers, dedicated HDD controllers, dedicated network
>> controllers etc.
>
>Nevertheless, simply making your program multi-threaded will not mean that
>it is guaranteed to run faster.

Although in many cases it may, simply because the OS can be cleverer
with the runtime process.

Such cases are of course likely to be the trivial ones but not always.
For example a multithreaded DB process may run considerably faster,
provided the threads don't need to access the same tables
simultaneously. This is a real-world example I worked on recently (in
Java I admit) which gained us several _hours_ off an overnight job.

>But my main point is that multithreading is not a magic wand

Absolutely.

>you can wave at
>any problem. It can certainly be used effectively, but it can also be used
>ineffectually, and can even be counter-productive.

Double-absolutely!

Mark McIntyre

unread,
Dec 28, 2006, 6:35:44 AM12/28/06
to
On Thu, 28 Dec 2006 10:18:33 +0100, in comp.lang.c , jacob navia
<ja...@jacob.remcomp.fr> wrote:

(of trigraphs, one of JN's favorite bugbears)


>
>I am just saying they are not needed any more.

Okay, so persuade the ISO committee, either directly or via your
national standards agency. Posting over in comp.std.c might prove
productive.

>Ahh bugs are BAD BAD.
>
>Great discovery. We are discussing how to avoid them if possible.
>One of the ways to avoid them is to make things automatic

Er, no. Remember the stock market crashes of the eighties?

The way to avoid bugs is to write bug-free code. :-)

>Why C is better than assembly?

Its not. Its merely different. Arguments based on language X being
"better" than language Y are the same as arguments that racial type Q
is better than racial type R, ie bullshit. Different languages serve
different purposes.

Mark McIntyre

unread,
Dec 28, 2006, 6:37:46 AM12/28/06
to
On Thu, 28 Dec 2006 11:08:48 +0100, in comp.lang.c , jacob navia
<ja...@jacob.remcomp.fr> wrote:

>Randy Howard a écrit :


>> Strawman. These are not equivalent at all. C gives you something
>> analogous to a Machete. Apparently, you would prefer a machete that is
>> never sharpened, only available with a special license, and has a hard
>> clear plastic cover such that it can't cut anything without melting it
>> off first with a blowtorch.
>
>To answer you in terms of your own analogy:
>
>C gives you a machette without a HANDLE.

No, C gives you a machete with a sharp blade. Its got a handle, and
plenty of us manage perfectly well to use it without cutting
ourselves.

>You can't use it without cutting yourself the hand.

if someone is incompetent, undertrained or lazy, sure. The same
argument can be applied to cars, toasters and pencil sharpeners by the
way.

jacob navia

unread,
Dec 28, 2006, 6:41:53 AM12/28/06
to
Mark McIntyre a écrit :

> On Thu, 28 Dec 2006 11:08:48 +0100, in comp.lang.c , jacob navia
> <ja...@jacob.remcomp.fr> wrote:
>
>
>>Randy Howard a écrit :
>>
>>>Strawman. These are not equivalent at all. C gives you something
>>>analogous to a Machete. Apparently, you would prefer a machete that is
>>>never sharpened, only available with a special license, and has a hard
>>>clear plastic cover such that it can't cut anything without melting it
>>>off first with a blowtorch.
>>
>>To answer you in terms of your own analogy:
>>
>>C gives you a machette without a HANDLE.
>
>
> No, C gives you a machete with a sharp blade. Its got a handle, and
> plenty of us manage perfectly well to use it without cutting
> ourselves.
>
>
>>You can't use it without cutting yourself the hand.
>
>
> if someone is incompetent, undertrained or lazy, sure. The same
> argument can be applied to cars, toasters and pencil sharpeners by the
> way.
>

Yes sure. Anything that improves security and allows for
less error prone interfaces is doomed to fail in this atmosphere
of "macho" programming.

It is pointless to discuss this. You never make mistakes
and those that do are "incompetent, undertrained, and lazy".

Richard Heathfield

unread,
Dec 28, 2006, 7:17:30 AM12/28/06
to
jacob navia said:

> Mark McIntyre a écrit :
>> On Thu, 28 Dec 2006 11:08:48 +0100, in comp.lang.c , jacob navia
>> <ja...@jacob.remcomp.fr> wrote:

<snip>
>>
>>>You can't use [C] without cutting yourself the hand.


>>
>>
>> if someone is incompetent, undertrained or lazy, sure. The same
>> argument can be applied to cars, toasters and pencil sharpeners by the
>> way.
>
> Yes sure. Anything that improves security and allows for
> less error prone interfaces is doomed to fail in this atmosphere
> of "macho" programming.

Not at all. The point you are missing is that there is more to programming
than "making it as easy as possible". Programming languages have various
characteristics, of which "ease of use" is only one. Others include
performance, portability, flexibility, expressive power, and simplicity (a
non-exhaustive list).

All of these characteristics are desirable, and programming languages
possess them in varying degrees. Sometimes, you can't increase one without
decreasing one or more of the others.

Programming language designers make choices which (whether they realise it
or not) enhance their language's "score" (to put it crudely) on some of
these characteristics but diminish it in others. Would that it were
possible to crank all of them up to the max! But it isn't.

And so we make trade-offs.

You appear to wish to promote one particular characteristic - ease of use -
without regard to the effect that such promotion will have on various other
characteristics. That's your choice, if you're implementing your own
language (or indeed if you are implementing extensions to C), but please
don't make the mistake of thinking that your choices should be binding on
everyone else just because *you* think they're good choices.

> It is pointless to discuss this. You never make mistakes
> and those that do are "incompetent, undertrained, and lazy".

It may indeed be pointless to discuss this with you, at least, because you
seem to be very ready to jump to conclusions that have little or no basis
in fact. Nobody in this discussion has claimed that they never make
mistakes, or that those who do are incompetent, undertrained, and lazy.

jacob navia

unread,
Dec 28, 2006, 8:06:20 AM12/28/06
to
Richard Heathfield a écrit :

> jacob navia said:
>
>
>>Mark McIntyre a écrit :
>>
>>>On Thu, 28 Dec 2006 11:08:48 +0100, in comp.lang.c , jacob navia
>>><ja...@jacob.remcomp.fr> wrote:
>
> <snip>
>
>>>>You can't use [C] without cutting yourself the hand.
>>>
>>>
>>>if someone is incompetent, undertrained or lazy, sure. The same
>>>argument can be applied to cars, toasters and pencil sharpeners by the
>>>way.
>>
>>Yes sure. Anything that improves security and allows for
>>less error prone interfaces is doomed to fail in this atmosphere
>>of "macho" programming.
>
>
> Not at all. The point you are missing is that there is more to programming
> than "making it as easy as possible". Programming languages have various
> characteristics, of which "ease of use" is only one. Others include
> performance, portability, flexibility, expressive power, and simplicity (a
> non-exhaustive list).
>

I am speaking not about "making it as easy as possible" (do not know
where you got that) but about "less error prone interfaces"!

This means that mind-dumbing requirements like having to take
care of all the millions of string lengths that you have got
in your program are to be banned. Interfaces should take
care automatically of string lengths. A string is a single
OBJECT composed of data and a length (counted strings),
and maybe other fields.

This is by the way vastly more efficient than counting
the length of the string at each usage, as you may know.

Of course this efficiency is maybe not desired. Is that what
you mean?

:-)

But anyway:

I have nothing against making it as easy AS POSSIBLE... Read well the
"AS POSSIBLE" part.

Simplifying, making interfaces less complex makes them less
error prone, and is surely a step in the right direction.

[snip]

> You appear to wish to promote one particular characteristic - ease of use -
> without regard to the effect that such promotion will have on various other
> characteristics.

When implementing the extensions in lcc-win32 nothing is paid by other
software that does not use them. All the extensions do not affect
in any way the rest of the language.

The performance implications of calling

MyAdd(Number *a, Number *b);

or doing
a+b;

are ZERO.

In both cases there is a function call.


> That's your choice, if you're implementing your own
> language (or indeed if you are implementing extensions to C), but please
> don't make the mistake of thinking that your choices should be binding on
> everyone else just because *you* think they're good choices.
>

I haven't made any decision for others since if you do not want those
extensions C strings and old fashioned arrays are still there.

You only pay for what you *actually use*.

Richard Heathfield

unread,
Dec 28, 2006, 8:25:25 AM12/28/06
to
jacob navia said:

> Richard Heathfield a écrit :

<snip>
>>
>> [...] The point you are missing is that there is more to


>> programming than "making it as easy as possible". Programming languages
>> have various characteristics, of which "ease of use" is only one. Others
>> include performance, portability, flexibility, expressive power, and
>> simplicity (a non-exhaustive list).
>
> I am speaking not about "making it as easy as possible" (do not know
> where you got that) but about "less error prone interfaces"!

I accept the correction (for I am not trying to misrepresent your view,
after all). To aim for less error-prone interfaces is a worthy goal, but
there are lots of worthy goals of which that is only one, and it is
unfortunately true that we cannot always get closer towards one goal
without moving further away from others.

> This means that mind-dumbing requirements like having to take
> care of all the millions of string lengths that you have got
> in your program are to be banned.

That's certainly an opinion, but I value freedom of choice. If you want to
offer people an extension which takes care of these "mind-numbing
requirements", that's entirely up to you, but let's not forget that it
comes at a cost - lock-in to a particular implementation - and not
everybody wants to pay that cost. It may also have other, less obvious
costs, such as performance degradation.

> Interfaces should take
> care automatically of string lengths. A string is a single
> OBJECT composed of data and a length (counted strings),
> and maybe other fields.

That's certainly an opinion, and it's not necessarily a bad one. It forms
the basis of typical third-party string libraries (including my own). But
to *force* people to use it is a step backwards. Your trade-off preferences
do not necessarily match everyone else's trade-off preferences.

> This is by the way vastly more efficient than counting
> the length of the string at each usage, as you may know.

That depends on how often you need the length of the string. It may be that
you don't need it often enough to justify the space or time overhead
involved in storing it.

> Of course this efficiency is maybe not desired. Is that what
> you mean?

No, I mean that it isn't *necessarily* the most efficient way. Often it will
be, but often isn't always.

> But anyway:
>
> I have nothing against making it as easy AS POSSIBLE... Read well the
> "AS POSSIBLE" part.
>
> Simplifying, making interfaces less complex makes them less
> error prone, and is surely a step in the right direction.

It's a step in *a* right direction, but unfortunately that may involve it
being a step *away* from other right directions.

> [snip]
>
>> You appear to wish to promote one particular characteristic - ease of use
>> - without regard to the effect that such promotion will have on various
>> other characteristics.
>
> When implementing the extensions in lcc-win32 nothing is paid by other
> software that does not use them. All the extensions do not affect
> in any way the rest of the language.

I have no problem with any implementor choosing to provide extensions to the
language, but it is important for the programmer to remember that using
such extensions renders the program non-portable.

> The performance implications of calling
>
> MyAdd(Number *a, Number *b);
>
> or doing
> a+b;
>
> are ZERO.

That depends on the implementation (including the machine architecture).

> In both cases there is a function call.

No, there is no function call involved in a+b; (unless a and b are macros
that are concealing function calls in their definition).

<snip>

Richard Bos

unread,
Dec 28, 2006, 8:31:24 AM12/28/06
to
Charlton Wilbur <cwi...@chromatico.net> wrote:

> jacob navia <ja...@jacob.remcomp.fr> writes:
>
> > Your opinion about lcc-win32 is second hand anyway since you
> > never use it. Your discussion so far presents no arguments but
> > "C strings are a design decision". So what? I know that.
> >
> > I am just saying that they were a BAD design decision.
>
> You know, when Bjarne Stroustrup decided he didn't like some of the
> limitations of C, he designed C++.
>
> When Brad Cox didn't like some of the limitations of C, he designed
> Objective-C.
>
> The problem here is not that you see design flaws in C. The problem
> is that you believe, in contravention of all evidence, that you can
> singlehandedly redesign C *and still call it C*.
>
> C is the language defined by K&R, K&R2, and the C89/90 and C99 standards.
>
> If you want a language remarkably like C, but with length-counted
> strings and garbage collection, hey, more power to you! It's likely
> to be a fine language, and possibly more useful, more efficient, and
> more resilient than C. But unless it conforms to the C standards, it
> isn't C.
>
> So why not design the language you really want, and call it something
> else?

I suspect something similar is at play here as with the kind of person
who wants to change a game to fit their own playing style - say,
NetHack, of which that has happened repeatedly - but also want to keep
the same name. The real clueful complainants go off and implement their
changes, and then call the result something else (Slash'Em). The jokers
stand on the sideline, and complain bitterly about how unfair this game
is to them.

Richard

Mark McIntyre

unread,
Dec 28, 2006, 8:47:38 AM12/28/06
to
On Thu, 28 Dec 2006 12:41:53 +0100, in comp.lang.c , jacob navia
<ja...@jacob.remcomp.fr> wrote:

>Mark McIntyre a écrit :
>> On Thu, 28 Dec 2006 11:08:48 +0100, in comp.lang.c , jacob navia
>> <ja...@jacob.remcomp.fr> wrote:
>>
>>
>>
>>>You can't use it without cutting yourself the hand.
>>
>> if someone is incompetent, undertrained or lazy, sure. The same
>> argument can be applied to cars, toasters and pencil sharpeners by the
>> way.
>
>Yes sure. Anything that improves security and allows for
>less error prone interfaces is doomed to fail in this atmosphere
>of "macho" programming.

I didn't say that, but then making false attributions seems to be a
forte of yours.
What I actually said is that your claim that its impossible to use C
without cutting yourself was generally untrue, that of course some
people will find it so depending on their level of skill and care, but
that the same could be said of many household objects.

Heck you can kill yourself with a cigarette lighter, yet they still
sell them without safety shields and with no requirement to have a
license to operate it.

>It is pointless to discuss this.

I agree. You're so blinkered with your rage against the regulars here,
and RJH in particular, that you can't be rational about anything, I
fear.

>You never make mistakes

Oh don't be silly. Of course I do, and I also accept that these may
lead to bugs. I do try to avoid them, and i do NOT rely on my toolset
to solve all my problems for me because I know that it too contains
bugs and is not omnipotent.

>and those that do are "incompetent, undertrained, and lazy".

People who make frequent mistakes of the sort you describe are one of
the above, yes.

Random832

unread,
Dec 28, 2006, 10:26:01 AM12/28/06
to
2006-12-28 <OtidnWMI9NO...@bt.com>,

Richard Heathfield wrote:
> João Jerónimo said:
>
>> Richard Heathfield wrote:
>>>> And typedefs make
>>>> defining recursive types (structures with pointers to themselves)
>>>> *more* complicated.
>>>
>>> Not agreed. The process is no more complicated than without typedef. The
>>> important thing to remember is that the type synonym isn't usable until
>>> the type exists.
>>
>> But on the other hand, a structure (in the structures namespace) can be
>> used before completely defined... It doesn't need to be defined, either!
>
> No, it can't be used before it is defined. But its *name* can be used in a
> typedef, yes.
>
>> In fact, I tried that now:
>> typedef struct garbage garb;
>
> Yes, that's legal.
>
>> gcc doesn't complain if I try to create an object from this code...
>
> When invoked in conforming mode, it must complain.

What would it's complaint be? How's GCC supposed to know that he's
trying to create an object when the actual code he writes is a mere
typedef?

I think you don't quite understand in what situation he's saying he
doesn't get an error.

Mark McIntyre

unread,
Dec 28, 2006, 11:14:42 AM12/28/06
to
On Thu, 28 Dec 2006 14:06:20 +0100, in comp.lang.c , jacob navia
<ja...@jacob.remcomp.fr> wrote:

>Interfaces should take
>care automatically of string lengths. A string is a single
>OBJECT composed of data and a length (counted strings),
>and maybe other fields.
>
>This is by the way vastly more efficient than counting
>the length of the string at each usage, as you may know.

This is a serius overstatement.

In cases where checking string length is done often, then doing it at
each usage is of course inefficient.

If on the other hand your programme /never/ needs to know the lengths
of strings, then being forced to use an object which includes the
overhead of stringsize is also inefficient.

I recall working on some code that assiduously checked for
divide-by-zero conditions before performing any division, even for
divisors such as 1+e^x. The check caused significant performance loss.
Had we been using an object that included "for free" a div/0 check, we
would have been faced with a major rewrite.
Elsewhere in the same code, there were numerous uses of strncpy
instead of strcpy. This gained nothing, not even performance, as the
source strings had been carefully loaded into a buffer of known width
and padded with blanks. The writer clearly thought it was a good idea
however, as they'd cleverly commented every single instance with a
warning not to change it.

The lesson to take from this is that efficiency is not a
one-size-fits-all solution, and one should not assume .

>Simplifying, making interfaces less complex makes them less
>error prone,

Sometimes, assuming the interface designer is competent and doesn't
make any mistakes, and with the price of less flexibility and
adaptability.

>and is surely a step in the right direction.

Again sometimes.

>The performance implications of calling
>
>MyAdd(Number *a, Number *b);
>
>or doing
> a+b;
>
>are ZERO.
>
>In both cases there is a function call.

Really?
the second involves loading two values into a register and calling ADD
or somesuch. Zero function calls.

The first might well involve creating a call stack, performing sanity
checks on the values, checking the result fits into a "Number"
whatever that is, and could easily take very much longer.

I've seen this done - I've seen novices who thought a clever way to be
overflow safe was to write functions to replace the operators, and
invariably their code ran like a dog.

Richard Heathfield

unread,
Dec 28, 2006, 11:22:10 AM12/28/06
to
Random832 said:

> 2006-12-28 <OtidnWMI9NO...@bt.com>,
> Richard Heathfield wrote:
>> João Jerónimo said:
>>
>>> Richard Heathfield wrote:
>>>>> And typedefs make
>>>>> defining recursive types (structures with pointers to themselves)
>>>>> *more* complicated.
>>>>
>>>> Not agreed. The process is no more complicated than without typedef.
>>>> The important thing to remember is that the type synonym isn't usable
>>>> until the type exists.
>>>
>>> But on the other hand, a structure (in the structures namespace) can be
>>> used before completely defined... It doesn't need to be defined, either!
>>
>> No, it can't be used before it is defined. But its *name* can be used in
>> a typedef, yes.
>>
>>> In fact, I tried that now:
>>> typedef struct garbage garb;
>>
>> Yes, that's legal.
>>
>>> gcc doesn't complain if I try to create an object from this code...
>>
>> When invoked in conforming mode, it must complain.
>
> What would it's complaint be?

Along the lines of "you are trying to create an object of a type that does
not exist."

> How's GCC supposed to know that he's
> trying to create an object when the actual code he writes is a mere
> typedef?

If that's how he's trying to create an object, then no complaint is
necessary, but neither will an object be created.

> I think you don't quite understand in what situation he's saying he
> doesn't get an error.

If he's trying to create an object of an incomplete type, either he's doing
it wrong (garb foo;) or he's doing it really wrong (using typedef, which
doesn't create objects). If the former, the compiler must complain. If the
latter, then I am reminded of the old saying, "That isn't right. That isn't
even wrong!"

Randy Howard

unread,
Dec 28, 2006, 11:46:40 AM12/28/06
to
On Thu, 28 Dec 2006 03:18:33 -0600, jacob navia wrote
(in article <45938be8$0$5114$ba4a...@news.orange.fr>):

> Randy Howard a écrit :
>>
>>>> No bugs so far.
>>>>
>>>
>>> Of course. Only "conscious design decisions", like trigraphs...
>>
>>
>> They served a purpose at the time they were designed in. If you're too
>> young to understand why, that's not a reason to pretend they were never
>> needed.
>>
>
> I am just saying they are not needed any more. Why they are here?

Right or wrong (usually the latter) backwards compatibility wins a lot
of arguments. Using the windows platform, you are no doubt well aware
of the results of this problem. Deal.

>> OTOH, if you have a bug due to you as a programmer directly violating
>> the rules of the language itself, that is not the fault of the
>> language. That is not knowing what you're doing.
>>
> Ahh bugs are BAD BAD.

They're certainly not good, other than as a means of obtaining more
experience in eliminating them.

> Great discovery. We are discussing how to avoid them if possible.

Sort of. You are discussing how your alternative language, which you
refuse to call by another name tackles avoiding some problems while
ignoring others. Several qualified language designers have made
attempts in that direction, but without the silliness of pretending the
resulting language is the same as C.

> One of the ways to avoid them is to make things automatic
> whenever possible so that the programmer has less to do, and less
> possibilities of errors.

That's also a way of removing control over how aspects of programming
are addressed, hoping the implementation is correct, but being less
able to correct it if it is not, and in all likelihood worsening
performance. Those are all tradeoffs, which may or may not be the
right decision for a given project.

> Why C is better than assembly?

It's not, generally speaking. It depends upon the project needs. In
some cases it is, in others it is not. The most common case being
where performance is important, but portability is even more so.

> Because the level of detail that you have to care about is less.
>
> You just write:
>
> c = a+b;
>
> and you do not have to care about which register you use,
> which address are b and c, etc etc.

mov and add instructions aren't particularly confusing for some, for
others they are apparently like trying to land a man on the moon.
Luckily, choices are available.

> If we have counted strings the length of the string is no longer
> a problem you have to manage but the string library.

You are free to use such things in standard C without mangling the
compiler. You are also free to use a compiler for something other than
C that does things differently. Then of course, that would be
off-topic for this newsgroup.

> If you use the GC you do not care about free(). One problem
> LESS to care about

If you use a shell script you don't have to worry about a compiler.

If you hire someone else to write it for you, you don't even have to
understand anything about the problem other than how to describe it.

You can carry this to any silly extent you desire. however, almost
none of that has a bearing on C.

Randy Howard

unread,
Dec 28, 2006, 11:49:55 AM12/28/06
to
On Thu, 28 Dec 2006 04:08:48 -0600, jacob navia wrote
(in article <459397af$0$5076$ba4a...@news.orange.fr>):

One problem. Your counter-example is false. C gives you a machete,
and a handle. The handle is the standard document that describes (in
painful detail) all aspects of the machete, how it works, how it should
be used, and in many cases how it should not be used. But, just like
people assembling toys the night before xmas for their children, too
often they don't read the instructions provided, and things go awry.

> I want to add a HANDLE to the machette i.e. a BLUNT
> side where I can handle it without getting my blood in my
> fingers...

People have been doing this for several decades. It's not immediately
obvious why you can not find a way to do the same.

Randy Howard

unread,
Dec 28, 2006, 12:02:46 PM12/28/06
to
On Thu, 28 Dec 2006 07:06:20 -0600, jacob navia wrote
(in article <4593c14c$0$25943$ba4a...@news.orange.fr>):

> Richard Heathfield a écrit :
>> jacob navia said:
>>
>>
>>> Mark McIntyre a écrit :
>>>

>> Not at all. The point you are missing is that there is more to programming
>> than "making it as easy as possible". Programming languages have various
>> characteristics, of which "ease of use" is only one. Others include
>> performance, portability, flexibility, expressive power, and simplicity (a
>> non-exhaustive list).
>>
>
> I am speaking not about "making it as easy as possible" (do not know
> where you got that) but about "less error prone interfaces"!

You have not demonstrated that fewer errors will result. You are
hoping that it will, and in that you may actually be correct. You are
also asking us to accept on faith that this implementation that does
all these things for us will do them without error, which they may do.

You're also /completely/ discounting the requirements that many of us
have to be able to compile code on a very wide array of platforms and
compilers. This requires some of us to play in a much smaller sandbox
than you are willing to acknowledge.

> This means that mind-dumbing requirements like having to take
> care of all the millions of string lengths that you have got
> in your program are to be banned.

I have to call BS now. You are in no position to "ban" anything. If
you are truly incapable of handling C style strings in your programs
without your mind becoming numb or other bad side-effects, then by all
means, find another language more suitable to your programming style.

What you are not to do, is pretend like determining for the rest of us
what we can and can not do in our programming is your bailiwick.

> I have nothing against making it as easy AS POSSIBLE... Read well the
> "AS POSSIBLE" part.

I have no need for it to be made easier. In fact, I claim that one of
the key contributors to the huge assortment of incredibly bad code on
the planet is that it has been made far too easy to produce software of
incredibly bad quality. Almost anyone can try, and far too many
succeed. If it were harder, we'd have less whining about making it
easier, and a lot more (as a percentage) qualified programmers, less
crappy software, etc. I realize I'm probably in the minority, and what
you or others would like to see is a programming language so simple
that even inmates in an asylum could produce their own operating
system. I hesitate to point out that this has apparently already
happened at least once, and the results are staggeringly bad.

> Simplifying, making interfaces less complex makes them less
> error prone, and is surely a step in the right direction.

In order to know if a step is in the right or wrong direction, you have
to know where the destination lies. More importantly, the answer is
different for each traveler, unless you happen to live somewhere where
everyone is identical (*shudder*)

>> You appear to wish to promote one particular characteristic - ease of use -
>> without regard to the effect that such promotion will have on various other
>> characteristics.
>
> When implementing the extensions in lcc-win32 nothing is paid by other
> software that does not use them. All the extensions do not affect
> in any way the rest of the language.

Fine and dandy. One minor problem though. It's not C. There is a
newsgroup for lcc if I'm not mistaken, and it's not this one. If you
want to evangelize on the merits of your language, give it a name,
write a paper on it, and get it published. Or perhaps start a blog, or
submit it to DDJ, there are a number of options, any of which are more
appropriate than what you are attempting here.

August Karlstrom

unread,
Dec 28, 2006, 12:05:29 PM12/28/06
to
newsm...@sbcglobal.net skrev:
> August Karlstrom <fusio...@comhem.se> wrote:
>> And what features specific to C enabled you to make the program that
>> much more efficient?
>
> 1) My friend and I have noticed that working with arrays in C are much faster than anything we compile with any other language. The programming concepts are the same, but the implementation on systems make C run faster on average
>
> (from our experience)

OK. I get about the same speed in Oberon though (with bound checks
turned off).

> 2) The built in library functions of bsearch and qsort work faster than using strings in C++ for doing much the same thing. (Obviously a lot faster then using BASH)

Sure, character arrays will always be more efficient (and less
convenient) than a "real" string type. (Oberon, as C, uses character
arrays for strings).

> I must say that these are observations that we have seen. I'm not stating they're a universal experience, have
> you had the same experience?

Yes. One approach is to use a high-level string type if (utmost)
efficiency is not an issue and use character arrays otherwise.


Regards,

August

jacob navia

unread,
Dec 28, 2006, 12:07:37 PM12/28/06
to
Mark McIntyre a écrit :

> On Thu, 28 Dec 2006 14:06:20 +0100, in comp.lang.c , jacob navia
> <ja...@jacob.remcomp.fr> wrote:
>
>
>>Interfaces should take
>>care automatically of string lengths. A string is a single
>>OBJECT composed of data and a length (counted strings),
>>and maybe other fields.
>>
>>This is by the way vastly more efficient than counting
>>the length of the string at each usage, as you may know.
>
>
> This is a serius overstatement.
>
> In cases where checking string length is done often, then doing it at
> each usage is of course inefficient.
>
> If on the other hand your programme /never/ needs to know the lengths
> of strings, then being forced to use an object which includes the
> overhead of stringsize is also inefficient.
>

Knowing the length is necessary for so many situations that in MOST
cases you will end up calling strlen explicitely or implicitely
(line in strcat)

In many cases you need to pass the string to another function.
In most cases you need to pass the length or the called function must
call strlen. To avoid an extra argument, most programmers will just
pass the string, forcing again a call to strlen. This is a horrible
waste with C string since in text handling programs, strings are passed
from function to function calling strlen for the same string over
and over.

String concatenation needs strlen implicitely.

Functions like strrchr can be coded MUCH more eficiently if the
length is known, since you start at the end of the string and stop
at the first match, instead of starting at the beginning, remembering
each match and returning the last...

To know if a string fits in a buffer you must know its length.

It is obvious that you can keep the length to avoid this
problems as heathfield says. But... if you need to keep the
length why not use a counted strings package anyway???

> I recall working on some code that assiduously checked for
> divide-by-zero conditions before performing any division, even for
> divisors such as 1+e^x.

??? Maybe a typo? You mean 1e+0 probably.

> The check caused significant performance loss.

Maybe, anything can be exaggerated by did you find that code
crashing with division by zero?

It depends on the way it was done. Yes, with an actual constant
as divisor you know it can't be a division by zero but the check
was written maybe BEFORE the constant. When the variable was
replaced by a constant the check was kept, maybe because he
did not know if it was OK to replace a variable with that
constant...


> Had we been using an object that included "for free" a div/0 check, we
> would have been faced with a major rewrite.

Maybe, but it doesn't hurt so much to be careful in
high reliability code...

> Elsewhere in the same code, there were numerous uses of strncpy
> instead of strcpy. This gained nothing, not even performance, as the
> source strings had been carefully loaded into a buffer of known width
> and padded with blanks. The writer clearly thought it was a good idea
> however, as they'd cleverly commented every single instance with a
> warning not to change it.
>

It wazs a principle thing, and I do not find that bad. Why should be
strncpy less efficient than strcpy???

Yes, it may be 0.0001% less efficient but maybe he did not see
"efficiency" as a higher goal than SECURITY!!!


> The lesson to take from this is that efficiency is not a
> one-size-fits-all solution, and one should not assume .
>

Never said otherwise but really, you are showing us cases that
are more or less exceptional. The repeated use of strlen over and over
the same string is obvious MUCH MORE COMMON than the cases you mention.

[snip]


>
>
>>The performance implications of calling
>>
>>MyAdd(Number *a, Number *b);
>>
>>or doing
>> a+b;
>>
>>are ZERO.
>>
>>In both cases there is a function call.
>
>
> Really?
> the second involves loading two values into a register and calling ADD
> or somesuch. Zero function calls.
>

You misunderstand. I was saying the usage of normal C functions in
contrast to operator overloading the '+' operation.

If you have some new type of number (rationals say) and you
use

RationalAdd(Rat a,rat b);

or a+b

is the same. That was my point.

>
> I've seen this done - I've seen novices who thought a clever way to be
> overflow safe was to write functions to replace the operators, and
> invariably their code ran like a dog.

Maybe.
1) lcc-win32 allows you to test for overflow, and the speed diffeerence
is almost zero when the compiler does it.
2) I am improving the operator overloading part, allowing inline and
assembly modules, so basically you will be able to do the overflow
test with almost no overhead.

Randy Howard

unread,
Dec 28, 2006, 12:11:29 PM12/28/06
to
On Thu, 28 Dec 2006 11:07:37 -0600, jacob navia wrote
(in article <4593f9d9$0$27371$ba4a...@news.orange.fr>):

>>> The performance implications of calling
>>>
>>> MyAdd(Number *a, Number *b);
>>>
>>> or doing
>>> a+b;
>>>
>>> are ZERO.
>>>
>>> In both cases there is a function call.
>>
>>
>> Really?
>> the second involves loading two values into a register and calling ADD
>> or somesuch. Zero function calls.
>>
>
> You misunderstand. I was saying the usage of normal C functions in
> contrast to operator overloading the '+' operation.
>
> If you have some new type of number (rationals say) and you
> use
>
> RationalAdd(Rat a,rat b);
>
> or a+b
>
> is the same. That was my point.

No wonder it was confusing. You made a claim in a C language newsgroup
about something (operator overloading) which doesn't even exist in the
C language. Worse, you didn't make it clear at all initially what you
were even referring to, or mark it as off-topic.

jacob navia

unread,
Dec 28, 2006, 12:14:13 PM12/28/06
to
Randy Howard a écrit :

> On Thu, 28 Dec 2006 11:07:37 -0600, jacob navia wrote
> (in article <4593f9d9$0$27371$ba4a...@news.orange.fr>):
>
>>>>The performance implications of calling
>>>>
>>>>MyAdd(Number *a, Number *b);
>>>>
>>>>or doing
>>>> a+b;
>>>>
>>>>are ZERO.
>>>>
>>>>In both cases there is a function call.
>>>
>>>
>>>Really?
>>>the second involves loading two values into a register and calling ADD
>>>or somesuch. Zero function calls.
>>>
>>
>>You misunderstand. I was saying the usage of normal C functions in
>>contrast to operator overloading the '+' operation.
>>
>>If you have some new type of number (rationals say) and you
>>use
>>
>>RationalAdd(Rat a,rat b);
>>
>>or a+b
>>
>>is the same. That was my point.
>
>
> No wonder it was confusing. You made a claim in a C language newsgroup
> about something (operator overloading) which doesn't even exist in the
> C language. Worse, you didn't make it clear at all initially what you
> were even referring to, or mark it as off-topic.
>

We were speaking of the possible performance penalties of this
extensions. Please read the whole tread before jumping to
conclusions.

jacob navia

unread,
Dec 28, 2006, 12:19:26 PM12/28/06
to
Richard Heathfield a écrit :

> jacob navia said:
>
> <snip>
>
>>I am just saying [trigraphs] are not needed any more. Why they are here?
>>Because a Danish manufacturer had problems with '{' and other
>>letters of the C alphabet. In the horse trading that goes behind
>>the publications of international standards they got into the
>>standard that trigraphs would be there to save them.
>>
>>Then, time passes, the manufacturer has disappeared since a long
>>time, and we are stuck with a nonsense construct!!!!
>
>
> So you claim. Nonetheless, trigraphs remain useful even now in, say,
> mainframe environments. But if you don't like trigraphs, don't use them.
>

I AM FORCED to used them. If I want it or not, the
translation will be done by the compiler without any user
intervention!

Richard Heathfield

unread,
Dec 28, 2006, 12:22:56 PM12/28/06
to
jacob navia said:

> Richard Heathfield a écrit :

<snip>

>> But if you don't like trigraphs, don't use them.


>>
>
> I AM FORCED to used them.

No, you're free to use some other language.

Randy Howard

unread,
Dec 28, 2006, 12:31:36 PM12/28/06
to
On Thu, 28 Dec 2006 11:14:13 -0600, jacob navia wrote
(in article <4593fb65$0$27371$ba4a...@news.orange.fr>):

Pot, kettle, black. You jumped to the conclusion that everyone reading
this line:

>>> or a+b

would automatically recognize that you meant the "+" operator meant
something other than what it actually does. I wasn't the only person
to not follow you along in your assumptions.

jacob navia

unread,
Dec 28, 2006, 1:00:45 PM12/28/06
to
Richard Heathfield a écrit :

> jacob navia said:
>
>
>>Richard Heathfield a écrit :
>
>
> <snip>
>
>>>But if you don't like trigraphs, don't use them.
>>>
>>
>>I AM FORCED to used them.
>
>
> No, you're free to use some other language.
>

Ahhh what an argumentation heathfield.

Incredible clever. I am sure you have pondered your answer
for hours.

David T. Ashley

unread,
Dec 28, 2006, 1:24:32 PM12/28/06
to
"jacob navia" <ja...@jacob.remcomp.fr> wrote in message
news:4591aa89$0$27371$ba4a...@news.orange.fr...
> The most glaring bugs in C are:
>
> 1) Zero terminated strings. This is the source of countless problems,
> because each access to a string implies an unbounded search for
> the terminating zero, and becasue size information is not stored
> explicitely in the string but must be reconstructed, so that
> buffer overflows when copying those strings are almost inevitable.

Not really a "bug". You can simply define your own data type and necessary
functions that operate on strings where the length information is
represented differently. People do this every day of the week.

'C' in general seems to be have been designed to avoid "hidden" operations
inserted by the compiler (which makes it fairly suitable for embedded work).
Aside from stack frames and the occasional unexpected library subroutine
call (for large integer math, for example), the 'C' statements are compiled
verbatim. There is very little going on behind the scenes.

The built-in data types in 'C' are low-maintenance and for the most part
directly supported by the machine's instruction set. Typically, nearly all
of the code is compiled inline without function calls unless you explicitly
call a function.

The paradigm is very direct and straightforward.

> so that
> buffer overflows when copying those strings are almost inevitable.

Firearms accidents and aircraft mishaps are also almost inevitable. Does
that mean that firearms and aircraft are bad? No, it means that inherently
dangerous and/or complex systems need more skilled operators.

Note that even a private pilot's license (the lowest rung on the ladder)
requires that you demonstrate to an FAA examiner that you can use reasonable
technique to take off and land an airplane. Individuals who can't do that
aren't allowed to operate an airplane. The licensing process explicitly
recognizes that aircraft are complicated.

On the other hand, anybody with $99.99 + local sales tax can bring the
wonders of 'C' to their Windows computer. With no training. And no
licensing. And then the accidents happen.

The frequent memory and pointer problems with 'C' aren't because of the
language. They are because idiots en masse are using a language that is not
designed to be idiot-proof.

> 2) Confusion between pointers and arrays. 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.

I agree to that these concepts are horribly confusing (*).

(*) To those who don't understand the language.

> 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.

There is an inherent conflict between (efficiency) and (silently carrying
around allocation information that isn't always needed). 'C' compiles well
because, among other reasons, the silent baggage is kept to a minimum.

Overall impression: your comments don't reflect design defects with 'C'.
Rather, they reflect a philosophical difference with the authors of the
language.

Richard Heathfield

unread,
Dec 28, 2006, 1:27:57 PM12/28/06
to

A simple examination of timestamps demonstrates otherwise. There was no need
to ponder.

jacob navia

unread,
Dec 28, 2006, 3:25:55 PM12/28/06
to
Richard Heathfield a écrit :
> jacob navia said:
>
>>Richard Heathfield a écrit :
>>
>>>jacob navia said:
>>>
>>>>Richard Heathfield a écrit :
>>>
>>><snip>
>>>
>>>>>But if you don't like trigraphs, don't use them.
>>>>
>>>>I AM FORCED to used them.
>>>
>>>No, you're free to use some other language.
>>
>>Ahhh what an argumentation heathfield.
>>
>>Incredible clever. I am sure you have pondered your answer
>>for hours.
>
>
> A simple examination of timestamps demonstrates otherwise. There was no need
> to ponder.
>

It would have been better that you turn on your brain
(as Dan Pop said) before answering in automatic mode
heathfield.

What is the point of your message?

You think we are in a sect where the guru can exclude
people that present dissenting views?

Or you think that if I go on posting in this group^,
working in my compiler, maintaining it, answering
mails since years it is because I think this language
is doomed?

Or what?

Just a moment reflection would have indicated you that if I use
the language I am FORCED to use trigraphs, as I am forced to
write a parentheses after an "if" keyword.

I am ready to accept a simple rule like that, it is very
easy and logical. But that
SomeFn(345); //What is this ????/
will make my code fail 100 lines below with an incomprehensible
"syntax error" no, that is not logical AT ALL.

All this because some terminals do not support '{'????/

Richard Heathfield

unread,
Dec 28, 2006, 4:52:33 PM12/28/06
to
jacob navia said:

<snip>



> It would have been better that you turn on your brain
> (as Dan Pop said) before answering in automatic mode
> heathfield.

It's rarely necessary when replying to you.

> What is the point of your message?

To answer your point.

> You think we are in a sect where the guru can exclude
> people that present dissenting views?

This newsgroup isn't about gurus and dissenting views, but about the C
programming language.

<snip>



> Just a moment reflection would have indicated you that if I use
> the language I am FORCED to use trigraphs, as I am forced to
> write a parentheses after an "if" keyword.

You need to know about trigraphs. You're not forced to use them.

> I am ready to accept a simple rule like that, it is very
> easy and logical. But that
> SomeFn(345); //What is this ????/
> will make my code fail 100 lines below with an incomprehensible
> "syntax error" no, that is not logical AT ALL.

Sure it is, to those who know the language.

> All this because some terminals do not support '{'????/

The workaround is simple - don't type lots of question marks. It's poor
style anyway.

Dik T. Winter

unread,
Dec 28, 2006, 7:09:05 PM12/28/06
to
In article <45938be8$0$5114$ba4a...@news.orange.fr> jacob navia <ja...@jacob.remcomp.fr> writes:
...
> > They served a purpose at the time they were designed in. If you're too
> > young to understand why, that's not a reason to pretend they were never
> > needed.
>
> I am just saying they are not needed any more. Why they are here?

> Because a Danish manufacturer had problems with '{' and other
> letters of the C alphabet.

Manufacturer? Where did you get that idea? The Danish users had problems
with them (and also users from some other countries). And indeed, the
following would look quite funny:

»include <stdio.h>
int main(void) æ
int aÆ5Ä;
return 0;
ä

BTW, on a French terminal of that time, the above would look like:
£include <stdio.h>
int main(void) é
int aº5§;
return 0;
è

> Then, time passes, the manufacturer has disappeared since a long
> time, and we are stuck with a nonsense construct!!!!

Which manufacturer?
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/

Mark McIntyre

unread,
Dec 28, 2006, 7:41:20 PM12/28/06
to
On Thu, 28 Dec 2006 18:07:37 +0100, in comp.lang.c , jacob navia
<ja...@jacob.remcomp.fr> wrote:

>Mark McIntyre a écrit :
>> On Thu, 28 Dec 2006 14:06:20 +0100, in comp.lang.c , jacob navia
>> <ja...@jacob.remcomp.fr> wrote:
>>
>>>This is by the way vastly more efficient than counting
>>>the length of the string at each usage, as you may know.
>>

>> In cases where checking string length is done often, then doing it at
>> each usage is of course inefficient.
>>
>> If on the other hand your programme /never/ needs to know the lengths
>> of strings, then being forced to use an object which includes the
>> overhead of stringsize is also inefficient.
>>
>Knowing the length is necessary for so many situations that in MOST
>cases you will end up calling strlen explicitely or implicitely

I disagree. You're once again generalising from your own extremely
limited experience to make wild sweeping statements about everyone
else's experience.

>In many cases you need to pass the string to another function.
>In most cases you need to pass the length or the called function must
>call strlen.

This doesn't follow even slightly. Stop putting up spurious arguments.


>To know if a string fits in a buffer you must know its length.

No, you need merely know that it cannot be larger than the buffer. I
don't expect you to understand the difference.

>It is obvious that you can keep the length to avoid this
>problems as heathfield says. But... if you need to keep the
>length why not use a counted strings package anyway???

If you need to handle div/0 sometimes, why always perform the check?

>> I recall working on some code that assiduously checked for
>> divide-by-zero conditions before performing any division, even for
>> divisors such as 1+e^x.
>
>??? Maybe a typo? You mean 1e+0 probably.

Buy a new calculator.

> > The check caused significant performance loss.
>
>Maybe, anything can be exaggerated by did you find that code
>crashing with division by zero?

Dur, it was impossible for it to crash with a div/0 error.

>> Had we been using an object that included "for free" a div/0 check, we
>> would have been faced with a major rewrite.
>
>Maybe, but it doesn't hurt so much to be careful in
>high reliability code...

In point of fact it hurt considerably because our pricing calculator
was slower than everyone else's to the extent that we missed deals.

>Yes, it may be 0.0001% less efficient but maybe he did not see
>"efficiency" as a higher goal than SECURITY!!!

Now you're being silly. Only an idiot makes remarks like that.

>> The lesson to take from this is that efficiency is not a
>> one-size-fits-all solution, and one should not assume .
>>
>
>Never said otherwise

Actually, you have repeatedly said exactly that.

>>>The performance implications of calling
>>>
>>>MyAdd(Number *a, Number *b);
>>>or doing
>>> a+b;
>>>
>>>are ZERO.
>>>
>>>In both cases there is a function call.
>>
>> Really?
>

>You misunderstand. I was saying the usage of normal C functions in
>contrast to operator overloading the '+' operation.

Ah, right, so you mean in some other language which has operator
overload. I thought you were talking about C.

>> I've seen this done - I've seen novices who thought a clever way to be
>> overflow safe was to write functions to replace the operators, and
>> invariably their code ran like a dog.
>
>Maybe.
>1) lcc-win32 allows you to test for overflow, and the speed diffeerence
> is almost zero when the compiler does it.

"almost zero". Mhm. Multiply by 10e12. Still almost zero?

>2) I am improving the operator overloading part, allowing inline and
> assembly modules, so basically you will be able to do the overflow
> test with almost no overhead.

I have no problem with you doing this, but don't call it C please.

Mark McIntyre

unread,
Dec 28, 2006, 7:46:10 PM12/28/06
to
On Thu, 28 Dec 2006 18:19:26 +0100, in comp.lang.c , jacob navia
<ja...@jacob.remcomp.fr> wrote:

>Richard Heathfield a écrit :


>>But if you don't like trigraphs, don't use them.
>
>I AM FORCED to used them.

What, someone is standing over you with a gun, compelling you to type
trigraphs whenever you want to type a brace? Don't be more asinine
than you need to be.

>If I want it or not, the
>translation will be done by the compiler without any user
>intervention!

If you mean your compiler has to support them, sure. But this does NOT
compel you to use them anywhere.

João Jerónimo

unread,
Dec 28, 2006, 11:19:59 PM12/28/06
to
Random832 wrote:
>>> gcc doesn't complain if I try to create an object from this code...
>> When invoked in conforming mode, it must complain.
>
> What would it's complaint be? How's GCC supposed to know that he's
> trying to create an object when the actual code he writes is a mere
> typedef?
>
> I think you don't quite understand in what situation he's saying he
> doesn't get an error.

I don't get an error if I try to produce an object (or assembly code)
from a C file that has *only* that typedef...

The goal was only see if it gives an error...

JJ

João Jerónimo

unread,
Dec 28, 2006, 11:28:10 PM12/28/06
to
Random832 wrote:
>>> gcc doesn't complain if I try to create an object from this code...
>> When invoked in conforming mode, it must complain.
>
> What would it's complaint be? How's GCC supposed to know that he's
> trying to create an object when the actual code he writes is a mere
> typedef?
>
> I think you don't quite understand in what situation he's saying he
> doesn't get an error.

The "object" I was talking about in the above sentence is a file with
relocatable machine code (before linking)...


It was only to see if GCC would produce any error when compiling
something like that, so I didn't need to link (and in fact couldn't link
that, because it lacked the main() function)...

JJ

João Jerónimo

unread,
Dec 28, 2006, 11:31:34 PM12/28/06
to
Richard Heathfield wrote:
>> If I try to access it before struct garbage exists it complains that it
>> doesn't know the size (because it needs to allocate space on the stack)...
>
> C doesn't require implementations to allocate space on any kind of "stack",
> but the type must be complete before you can define an object of that type.

But afaik it requires the functions to be reentrant (does it require?
I'm not sure, but suppose so...), and allocating local variables in a
stack seems the only way to achieve this...

JJ

João Jerónimo

unread,
Dec 29, 2006, 12:12:54 AM12/29/06
to
Richard Heathfield wrote:
>> In my opinion (not very experienced, I admit), the types with imprecise
>> size aren't bad... Only there could *also* be the precise ones.
>
> Fine, but eventually people will say "why does C have this
> guaranteed-to-be-exactly-8-bits type? Nobody has used 8-bit bytes for
> *decades*!" And we will not even have the excuse of "historical reasons",
> since C started off *without* such a type.

I don't believe that people would say "why does C have this
guaranteed-to-be-exactly-8-bits type?", because today many people ask
"How can I guarantee that this type will be a x-bit integer?"...

Not exactly in user space, but, as I said below, in hardware-imposed
patterns...

>> Remember that when programming in very low-level, one has sometimes to
>> adapt data structures to hardware-imposed patterns...
>
> ...which is why C leaves the exact size of types up to the implementor.

I thought this was done to increase portability...

>> And typedefs allow working around this.
>
> No, they just let you create a new name for an existing type.

It's in the c.l.c FAQ:
http://c-faq.com/decl/int16.html

>>>> This was difficult in the time when C was designed, because of the
>>>> diversity of architectures at the time (I think there were
>>>> bit-addressable machines, right?)...
>>>> But now "byte" is a synonym of "octet", right?
>>> Wrong. Numerous counter-examples exist.
>> Can you give some of these examples?
>
> I can give you one, because it's one that I have written C code for: the
> Analog SHARC DSP (used in set-top boxes, e.g. DVD players, Web TV, that
> sort of thing), which has 32-bit bytes. So sizeof(long), sizeof(short),
> sizeof(int), and sizeof(char) are all the same: 1.
>
> No doubt others here can tell you about other DSPs with 16- or 32-bit bytes.
> They're hardly rare. Also, various dinosaurs have had very weird byte
> sizes, e.g. 9, 36, and I believe there was once a 24 (BICBW).
>
> All that C guarantees is that your bytes will be *at least* 8 bits wide, and
> *exactly* CHAR_BIT bits wide, where the value of CHAR_BIT is set by the
> implementation.


Thanks, I thought all that strange machines were already dinosaurs...

JJ

CBFalconer

unread,
Dec 28, 2006, 7:22:37 PM12/28/06
to
Randy Howard wrote:
> On Thu, 28 Dec 2006 11:14:13 -0600, jacob navia wrote
>
... snip ...

>>
>> We were speaking of the possible performance penalties of this
>> extensions. Please read the whole tread before jumping to
>> conclusions.
>
> Pot, kettle, black. You jumped to the conclusion that everyone
> reading this line:
>
>>>> or a+b
>
> would automatically recognize that you meant the "+" operator
> meant something other than what it actually does. I wasn't the
> only person to not follow you along in your assumptions.

It is high time to PLONK this thread. Enjoy your war.

--
Merry Christmas, Happy Hanukah, Happy New Year
Joyeux Noel, Bonne Annee.
Chuck F (cbfalconer at maineline dot net)
<http://cbfalconer.home.att.net>


av

unread,
Dec 29, 2006, 1:07:36 AM12/29/06
to
On Wed, 27 Dec 2006 07:17:46 +0100, jacob navia wrote:
>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.

it is possible this is an error too but it seems
now memory leak not happen to me, and i presume 99% of out of bound
array rewriting too using my modificating version of malloc and free

av

unread,
Dec 29, 2006, 1:10:32 AM12/29/06
to
On Thu, 28 Dec 2006 18:07:37 +0100, jacob navia wrote:
>Knowing the length is necessary for so many situations that in MOST
>cases you will end up calling strlen explicitely or implicitely
>(line in strcat)
>
>In many cases you need to pass the string to another function.
>In most cases you need to pass the length or the called function must
>call strlen. To avoid an extra argument, most programmers will just
>pass the string, forcing again a call to strlen. This is a horrible
>waste with C string since in text handling programs, strings are passed
>from function to function calling strlen for the same string over
>and over.

this depends on functions that write the arrays if
0) we have an array "char a[59];"
1) if a function change "a" and return its new len
or if i change "a" i know the new len
we know always the new len of "a"

in c there are function that modify array but not return the len
bugged from definition

Richard Heathfield

unread,
Dec 29, 2006, 1:33:25 AM12/29/06
to
João Jerónimo said:

> Richard Heathfield wrote:
>>> In my opinion (not very experienced, I admit), the types with imprecise
>>> size aren't bad... Only there could *also* be the precise ones.
>>
>> Fine, but eventually people will say "why does C have this
>> guaranteed-to-be-exactly-8-bits type? Nobody has used 8-bit bytes for
>> *decades*!" And we will not even have the excuse of "historical reasons",
>> since C started off *without* such a type.
>
> I don't believe that people would say "why does C have this
> guaranteed-to-be-exactly-8-bits type?", because today many people ask
> "How can I guarantee that this type will be a x-bit integer?"...

They do? I rarely see anyone asking that question. And it's rarer still for
someone to ask that question with good reason.

> Not exactly in user space, but, as I said below, in hardware-imposed
> patterns...
>
>>> Remember that when programming in very low-level, one has sometimes to
>>> adapt data structures to hardware-imposed patterns...
>>
>> ...which is why C leaves the exact size of types up to the implementor.
>
> I thought this was done to increase portability...

Yes. The two statements are equivalent.


>>> And typedefs allow working around this.
>>
>> No, they just let you create a new name for an existing type.
>
> It's in the c.l.c FAQ:
> http://c-faq.com/decl/int16.html

The FAQ says, rightly, "if you truly need control over exact type sizes,
this is the right approach." And as it strongly hints, you almost certainly
don't *really* need control over exact type sizes after all.

>>>>> But now "byte" is a synonym of "octet", right?
>>>> Wrong. Numerous counter-examples exist.
>>> Can you give some of these examples?
>>
>> I can give you one, because it's one that I have written C code for: the
>> Analog SHARC DSP (used in set-top boxes, e.g. DVD players, Web TV, that
>> sort of thing), which has 32-bit bytes. So sizeof(long), sizeof(short),
>> sizeof(int), and sizeof(char) are all the same: 1.
>>
>> No doubt others here can tell you about other DSPs with 16- or 32-bit
>> bytes. They're hardly rare. Also, various dinosaurs have had very weird
>> byte sizes, e.g. 9, 36, and I believe there was once a 24 (BICBW).
>>
>> All that C guarantees is that your bytes will be *at least* 8 bits wide,
>> and *exactly* CHAR_BIT bits wide, where the value of CHAR_BIT is set by
>> the implementation.
>
> Thanks, I thought all that strange machines were already dinosaurs...

In terms of byte sizes, you ain't seen nuffin' yet.

jacob navia

unread,
Dec 29, 2006, 3:36:08 AM12/29/06
to
Mark McIntyre a écrit :
> On Thu, 28 Dec 2006 18:07:37 +0100, in comp.lang.c , jacob navia
> <ja...@jacob.remcomp.fr> wrote:
>
>
>>Mark McIntyre a écrit :
>>
>>>On Thu, 28 Dec 2006 14:06:20 +0100, in comp.lang.c , jacob navia
>>><ja...@jacob.remcomp.fr> wrote:
>>>
>>>
>>>>This is by the way vastly more efficient than counting
>>>>the length of the string at each usage, as you may know.
>>>
>>>In cases where checking string length is done often, then doing it at
>>>each usage is of course inefficient.
>>>
>>>If on the other hand your programme /never/ needs to know the lengths
>>>of strings, then being forced to use an object which includes the
>>>overhead of stringsize is also inefficient.
>>>
>>
>>Knowing the length is necessary for so many situations that in MOST
>>cases you will end up calling strlen explicitely or implicitely
>
>
> I disagree. You're once again generalising from your own extremely
> limited experience to make wild sweeping statements about everyone
> else's experience.
>

And you are speaking about something you do not know at all: me.
Where is your data about me? Where you know what experience I have or
not?

You don't. Period. The one making sweeping statements is you.

>
>>In many cases you need to pass the string to another function.
>>In most cases you need to pass the length or the called function must
>>call strlen.
>
>
> This doesn't follow even slightly. Stop putting up spurious arguments.
>

No?

How do you pass the length of the string then?


>>To know if a string fits in a buffer you must know its length.
>
>
> No, you need merely know that it cannot be larger than the buffer. I
> don't expect you to understand the difference.
>

Gosh! You are clever. And how can I know if the given string
is bigger than the buffer without at least trying to measure
the length?

int fn(char *str)
{
char tmpbuf[512];
/* Here I have to start scanning the string.
At least 511 bytes must be scanned before
I realize that the length of the string is bigger
than tmpbuf. For bigger buffers a bigger WASTE
*/
}

>
>>It is obvious that you can keep the length to avoid this
>>problems as heathfield says. But... if you need to keep the
>>length why not use a counted strings package anyway???
>
>
> If you need to handle div/0 sometimes, why always perform the check?
>

Because you never know when software will change and a constant
becomes a variable...

>
>>>I recall working on some code that assiduously checked for
>>>divide-by-zero conditions before performing any division, even for
>>>divisors such as 1+e^x.
>>
>>??? Maybe a typo? You mean 1e+0 probably.
>
>
> Buy a new calculator.
>

??? You mean 1+e^x in C?

Or you mean pow(e,x)+1 ?

>
>>>The check caused significant performance loss.
>>
>>Maybe, anything can be exaggerated by did you find that code
>>crashing with division by zero?
>
>
> Dur, it was impossible for it to crash with a div/0 error.
>
>
>>>Had we been using an object that included "for free" a div/0 check, we
>>>would have been faced with a major rewrite.
>>
>>Maybe, but it doesn't hurt so much to be careful in
>>high reliability code...
>
>
> In point of fact it hurt considerably because our pricing calculator
> was slower than everyone else's to the extent that we missed deals.
>

Ahh and it was slower because of the division by zero tests?

I would like to see the data that supports that hypothesis.
With today's machines, a test for zero is so fast that to slow
down a calculator so that a human being notices the tests must have
been done in an incredible fashion, and probably there are
thousands of OTHER factors that come into the slowdown first.

>
>>Yes, it may be 0.0001% less efficient but maybe he did not see
>>"efficiency" as a higher goal than SECURITY!!!
>
>
> Now you're being silly. Only an idiot makes remarks like that.
>

Obvious coming from you. Only idiots make remarks like

"efficiency" is not a higher goal than SECURITY.

Yes. Only an idiot can do a remark like that.

This finishes it. You, you are not AN IDIOT!

Mark McIntyre

unread,
Dec 29, 2006, 4:39:28 AM12/29/06
to
On Fri, 29 Dec 2006 09:36:08 +0100, in comp.lang.c , jacob navia
<ja...@jacob.remcomp.fr> wrote:

>And you are speaking about something you do not know at all: me.

Au contaire, cheri.

>Where is your data about me? Where you know what experience I have or
>not?

You've demonstrated your experience in this newsgroup on numerous
occasions. If you have different experience to that which you display
here, then show it.

>You don't. Period. The one making sweeping statements is you.

I'm not the one making sweeping statements claiming that it is
essential to know the length of a string.

>How do you pass the length of the string then?

With correct design, you don't need to .

>> No, you need merely know that it cannot be larger than the buffer. I
>> don't expect you to understand the difference.
>>
>
>Gosh! You are clever. And how can I know if the given string
>is bigger than the buffer without at least trying to measure
>the length?

By knowing its length already, of course.

>int fn(char *str)
>{
> char tmpbuf[512];
> /* Here I have to start scanning the string.
> At least 511 bytes must be scanned before
> I realize that the length of the string is bigger
> than tmpbuf. For bigger buffers a bigger WASTE
> */
>}

Is it /my/ fault if you have a badly designed programme? Where did
"str" come from? How did you create it? Did you define its length when
you did so?

To put you out of your misery, the app in question read strings into
fixed length buffers, padded them with blanks and null-terminated
them. Thus the strings were /always/ exactly N characters long, no
more and no less. This removed any need at all anywhere to calculate
how long the strings were, because we already knew.

>> If you need to handle div/0 sometimes, why always perform the check?
>
>Because you never know when software will change and a constant
>becomes a variable...

Two points here
a) constants have nothing to do with it.
b) designing an application for a series of unknown future changes for
unguessable purposes by maintenance droids of unknown quality is both
inefficient and foolish.
I also strongly suspect you're not a follower of XP. They'd shoot you
for doing that sort of thing. :-)

>> In point of fact it hurt considerably because our pricing calculator
>> was slower than everyone else's to the extent that we missed deals.
>
>Ahh and it was slower because of the division by zero tests?

Yes. How do I know? I measured it. Next question.

>I would like to see the data that supports that hypothesis.

Sure. Get yourself employed by my former employer, and you can look at
my project post-implementation report. Its in the files of the
Technology Dept somewhere.

>With today's machines, a test for zero is so fast

And you've proved this beyond all doubt on Vax/VMS, Vax/OSF,
Sun/Solaris, Windows NT/PIII, all of which were targets.

>that to slow
>down a calculator so that a human being notices the tests must have
>been done in an incredible fashion,

Or incredibly often. You apparently have no experience of numerical
pricing techniques either. Ever heard of monte-carlo simulation?

>>>Yes, it may be 0.0001% less efficient but maybe he did not see
>>>"efficiency" as a higher goal than SECURITY!!!
>>
>> Now you're being silly. Only an idiot makes remarks like that.
>>
>
>Obvious coming from you.

The point you miss is that security and efficiency are not mutually
exclusive, nor is one axiomatically more important than the other.
Again you generalise unacceptably.

>This finishes it. You, you are not AN IDIOT!

I'm glad we agree I'm not an idiot. I know that of course.

Keith Thompson

unread,
Dec 29, 2006, 4:40:03 AM12/29/06
to

It's easy to create C functions that aren't reentrant (e.g., if they
use variables that have static storage duration). The requirement is
that functions must be callable recursively, which is different from
being reentrant.

Local variables (more precisely, objects with automatic storage
duration) must be allocated and deallocated in a stack-like manner
(though a compiler may be able to avoid this if it can prove that the
function is never called recursively). But what most people mean by
"the stack" is a contiguously allocated region of memory indexed by a
"stack pointer" (which is typically a CPU register), that grows in a
specific direction in memory. Many (most?) C implementations use this
kind of "stack", but it's not required. An implementation could, for
example, use malloc() or something similar to allocate local variables
for each function call, and free() or something similar to deallocate
them.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

Mark McIntyre

unread,
Dec 29, 2006, 4:40:16 AM12/29/06
to
On Thu, 28 Dec 2006 19:22:37 -0500, in comp.lang.c , CBFalconer
<cbfal...@yahoo.com> wrote:

>It is high time to PLONK this thread. Enjoy your war.

I agree, its been fun but EOT for me.

Richard Bos

unread,
Dec 29, 2006, 6:01:19 AM12/29/06
to
jacob navia <ja...@jacob.remcomp.fr> wrote:

> Mark McIntyre a écrit :
> > On Thu, 28 Dec 2006 14:06:20 +0100, in comp.lang.c , jacob navia
> > <ja...@jacob.remcomp.fr> wrote:
> >
> >>Interfaces should take
> >>care automatically of string lengths. A string is a single
> >>OBJECT composed of data and a length (counted strings),
> >>and maybe other fields.


> >>
> >>This is by the way vastly more efficient than counting
> >>the length of the string at each usage, as you may know.
> >

> > This is a serius overstatement.

> >
> > In cases where checking string length is done often, then doing it at
> > each usage is of course inefficient.
> >
> > If on the other hand your programme /never/ needs to know the lengths
> > of strings, then being forced to use an object which includes the
> > overhead of stringsize is also inefficient.
>
> Knowing the length is necessary for so many situations that in MOST
> cases you will end up calling strlen explicitely or implicitely

> (line in strcat)

Since you are eager to claim this just about every time you advertise
your Pascal-strings scheme, against the advice of nearly everybody who,
unlike you or I, actually _is_ an expert, I'm sure you have done
extensive research on this issue and have lots of real world data to
prove that the experts are wrong and you are right. I qould suggest that
you show this data.

> problems as heathfield says. But... if you need to keep the

His name, unlike yours (as stated in your own headers), starts with a
capital. Common decency is free.

> > I recall working on some code that assiduously checked for
> > divide-by-zero conditions before performing any division, even for
> > divisors such as 1+e^x.
>
> ??? Maybe a typo? You mean 1e+0 probably.

Not at all. 1e+0 is merely a very stupid way to write 1 in C. 1+e^x is
not a C expression but a maths one, and if you remember the range of
your exponents, it is easy to figure out why a zero check for it is
silly.

> > The check caused significant performance loss.
>
> Maybe, anything can be exaggerated by did you find that code
> crashing with division by zero?

Ignoring the wonky grammar, I think you'll find (if you read the
expression quoted above correctly) that Mark could easily prove that
there would be no crash.

> > Elsewhere in the same code, there were numerous uses of strncpy
> > instead of strcpy. This gained nothing, not even performance, as the
> > source strings had been carefully loaded into a buffer of known width
> > and padded with blanks. The writer clearly thought it was a good idea
> > however, as they'd cleverly commented every single instance with a
> > warning not to change it.
> >
>
> It wazs a principle thing, and I do not find that bad. Why should be
> strncpy less efficient than strcpy???


>
> Yes, it may be 0.0001% less efficient

You have measured this? You have even done the maths? Others have.

> > The lesson to take from this is that efficiency is not a
> > one-size-fits-all solution, and one should not assume .
>

> Never said otherwise but really, you are showing us cases that
> are more or less exceptional. The repeated use of strlen over and over
> the same string is obvious MUCH MORE COMMON than the cases you mention.

Again: data, please. _Real_ data, not your personal code.

> >>The performance implications of calling
> >>
> >>MyAdd(Number *a, Number *b);
> >>
> >>or doing
> >> a+b;
> >>
> >>are ZERO.
> >>
> >>In both cases there is a function call.
> >
> > Really?

> > the second involves loading two values into a register and calling ADD
> > or somesuch. Zero function calls.
>

> You misunderstand. I was saying the usage of normal C functions in
> contrast to operator overloading the '+' operation.

You cannot overload the '+' operation. Unless you think you're in
comp.lang.c++, which is the next door down the corridor.


Basically, jacob, you're arguing against _real_ experts, and basing your
arguments on suppositions and loose sand. That's no way to be taken
seriously.

Richard

João Jerónimo

unread,
Dec 29, 2006, 12:02:58 PM12/29/06
to
Keith Thompson wrote:
> João Jerónimo <j_j_...@yahoo.com.br> writes:
>> Richard Heathfield wrote:
>>>> If I try to access it before struct garbage exists it complains that it
>>>> doesn't know the size (because it needs to allocate space on the stack)...
>>> C doesn't require implementations to allocate space on any kind of "stack",
>>> but the type must be complete before you can define an object of that type.
>> But afaik it requires the functions to be reentrant (does it require?
>> I'm not sure, but suppose so...), and allocating local variables in a
>> stack seems the only way to achieve this...
>
> It's easy to create C functions that aren't reentrant (e.g., if they
> use variables that have static storage duration). The requirement is
> that functions must be callable recursively, which is different from
> being reentrant.

Ok, but apart from code that is explicitly non-reentrant (because it
allocates data with limited scoop in a statical fashion), C code will be
reentrant, meaning that any function can call any function, including
itself, without having the functions' "instances" conflicting with each
other...

JJ

Keith Thompson

unread,
Dec 29, 2006, 2:48:23 PM12/29/06
to
João Jerónimo <j_j_...@yahoo.com.br> writes:
> Keith Thompson wrote:
>> João Jerónimo <j_j_...@yahoo.com.br> writes:
[...]

>> It's easy to create C functions that aren't reentrant (e.g., if they
>> use variables that have static storage duration). The requirement is
>> that functions must be callable recursively, which is different from
>> being reentrant.
>
> Ok, but apart from code that is explicitly non-reentrant (because it
> allocates data with limited scoop in a statical fashion), C code will be
> reentrant, meaning that any function can call any function, including
> itself, without having the functions' "instances" conflicting with each
> other...

Yes, C functions are reentrant unless they're not.

More seriously, the automatic objects declared within a function
(including the parameters) are guaranteed to be distinct for each call
to that function. This is subject to the "as-if" rule; a compiler is
allowed to optimize the code as long as the code can't tell tell the
difference (more or less).

Dave Vandervies

unread,
Dec 29, 2006, 8:22:44 PM12/29/06
to
In article <4593f9d9$0$27371$ba4a...@news.orange.fr>,
jacob navia <ja...@jacob.remcomp.fr> wrote:
>Mark McIntyre a écrit :

>> This is a serius overstatement.
>>
>> In cases where checking string length is done often, then doing it at
>> each usage is of course inefficient.
>>
>> If on the other hand your programme /never/ needs to know the lengths
>> of strings, then being forced to use an object which includes the
>> overhead of stringsize is also inefficient.
>>
>
>Knowing the length is necessary for so many situations that in MOST
>cases you will end up calling strlen explicitely or implicitely
>(line in strcat)
>

>In many cases you need to pass the string to another function.
>In most cases you need to pass the length or the called function must

>call strlen. To avoid an extra argument, most programmers will just
>pass the string, forcing again a call to strlen. This is a horrible
>waste with C string since in text handling programs, strings are passed
>from function to function calling strlen for the same string over
>and over.

If knowing the length of strings is that important, can you explain
how counted strings would have made this code easier to write, clearer,
or less error-prone?
(This is the least-trivial string processing code I've written in recent
memory, so it's as close to a representative example as I can give.)

For anybody else who's following along, commentary and suggestions about
the code itself is also welcome. (It does require an ASCII system,
which seemed like a suitable restriction since the data it works with is
defined to be ASCII. The character set dependency could be eliminated
if necessary by writing the ASCII code points and case conversion into
the code instead of using character constants and toupper, and I think
that if that were done this code could be inserted into a strictly
conforming C program without affecting its strictly-conforming-ness
modulo translation limits.)


/* -8<--Code starts here--8<- */
#include <assert.h>
#include <ctype.h>
#include <string.h>

/*Verify checksum (if present) and split fields in a NMEA sentence.
Inputs:
sentence is a string containing the NMEA sentence.
This string IS MODIFIED on successful completion.
fields is an array of char *. On successful return, fields[i]
contains a pointer to the ith field of the sentence (fields[0]
is the sentence identifier and fields[ret-1] is the last data
field).
nfields is the maximum number of fields to unpack.
Return value:
If sentence does not contain a correctly formatted NMEA sentence or
contains a sentence with an incorrect checksum, returns 0 and does
not modify sentence or fields.
If nfields is too small, returns negative value such that -ret is the
number of fields needed and does not modify sentence or fields.
On success, returns the number of fields unpacked, and modifies
sentence by replacing all field separators (commas and the '*' or
'\r' following the data) with '\0' to allow fields[i] to point
into the original string.
Correctly formatted NMEA sentences have the form
"$TTSSS,comma,separated,fields*CC\r\n" for checksummed sentences or
"$TTSSS,comma,separated,fields\r\n" for non-checksummed sentences.
The contents (other than commas) of the fields between the initial '$'
and the terminating '*' or '\r', and any characters after the checksum
or after the '\r' for sentences without a checksum, are ignored here.
The sentence need not start at the beginning of the string. If the
string contains more than one sentence, all but the first will be
ignored.
*/
int unpack_nmea(char *sentence,char **fields, int nfields)
{
static char *hexdigits="0123456789ABCDEF";
int needed;
char *start,*ptr;
char cksum=0;
int i;

ptr=start=strchr(sentence,'$');
if(!ptr)
{
/*No '$' to start sentence*/
return 0;
}

/*First pass: Check checksum and count fields*/
ptr++;
needed=1;
while(*ptr && *ptr!='*' && *ptr!='\r')
{
if(*ptr==',')
{
needed++;
}
cksum^=*ptr;
ptr++;
}

/*Now we can check whether the input is well-formed...*/
if(*ptr=='0')
{
/*Not a well-formed sentence (no terminator)*/
return 0;
}
if(*ptr=='*')
{
/*Checksummed sentence, verify checksum*/
if(toupper(ptr[1])!=hexdigits[cksum>>4]
|| toupper(ptr[2])!=hexdigits[cksum&0xf])
{
/*Checksum error*/
return 0;
}
}

/*...and whether we have enough space to pack the output*/
if(needed>nfields)
return -needed;

/*Now we just have to split up the string and pack fields[]*/
ptr=start;
for(i=0;i<needed;i++)
{
ptr++;
fields[i]=ptr;
ptr+=strcspn(ptr,",*\r");
assert(*ptr==',' || *ptr=='*' || *ptr=='\r');
*ptr=0;
}

return needed;
}
/* -8<--Code ends here--8<- */


dave

--
Dave Vandervies dj3v...@csclub.uwaterloo.ca
[Y]es, I am seriously advocating that you should make sure your buffer is big
enough to store stuff you want to store in that buffer. Are you seriously
advocating that you should not? --Richard Heathfield in comp.lang.c

João Jerónimo

unread,
Dec 30, 2006, 12:01:04 AM12/30/06
to
Keith Thompson wrote:
>> Ok, but apart from code that is explicitly non-reentrant (because it
>> allocates data with limited scoop in a statical fashion), C code will be
>> reentrant, meaning that any function can call any function, including
>> itself, without having the functions' "instances" conflicting with each
>> other...
>
> Yes, C functions are reentrant unless they're not.

:-)

JJ

jacob navia

unread,
Dec 30, 2006, 3:18:34 AM12/30/06
to
Dave Vandervies a écrit :

>
> If knowing the length of strings is that important, can you explain
> how counted strings would have made this code easier to write, clearer,
> or less error-prone?
>
>
> /* -8<--Code starts here--8<- */
> #include <assert.h>
> #include <ctype.h>
> #include <string.h>
>
> int unpack_nmea(char *sentence,char **fields, int nfields)
> {
> static char *hexdigits="0123456789ABCDEF";
> int needed;
> char *start,*ptr;
> char cksum=0;
> int i;
>
> ptr=start=strchr(sentence,'$');
-------
In the strchr call above, a counted strings implementation can
safely replace a strchr with memchr, that doesn't check at each
character the terminating zero but just makes a bounded
memory scan
---------

> if(!ptr)
> {
> /*No '$' to start sentence*/
> return 0;
> }
>
> /*First pass: Check checksum and count fields*/
> ptr++;
> needed=1;
> while(*ptr && *ptr!='*' && *ptr!='\r')
> {
--------
Here the string library provides
Strfind_firstof(String, setOfChars);
--------

> if(*ptr==',')
> {
> needed++;
> }
> cksum^=*ptr;
> ptr++;
> }
>
> /*Now we can check whether the input is well-formed...*/
> if(*ptr=='0')
-------
Are you sure you are testing for the character zero ('0') and
not for the terminating zero ( 0 ) ?????????
-------

> {
> /*Not a well-formed sentence (no terminator)*/
> return 0;
> }
> if(*ptr=='*')
> {
> /*Checksummed sentence, verify checksum*/
> if(toupper(ptr[1])!=hexdigits[cksum>>4]
> || toupper(ptr[2])!=hexdigits[cksum&0xf])
> {
> /*Checksum error*/
> return 0;
> }
> }
>
> /*...and whether we have enough space to pack the output*/
> if(needed>nfields)
> return -needed;
>
> /*Now we just have to split up the string and pack fields[]*/
> ptr=start;
> for(i=0;i<needed;i++)
> {
> ptr++;
> fields[i]=ptr;
> ptr+=strcspn(ptr,",*\r");
---------
The counted strcspn version needs NOT to test for a terminating zero
but just for the pattern being searched
---------

> assert(*ptr==',' || *ptr=='*' || *ptr=='\r');
> *ptr=0;
> }
>
> return needed;
> }
> /* -8<--Code ends here--8<- */
>
>
> dave
>


But I may disappoint you since in the implementation of lcc-win32 the
strings are probably much slower than they ought to be since the
main thrust of the package is to provide more security and not speed.

I will start a faster version soon.

As you can see, the main advantages are the obviating for the tests
for the zero byte.

jacob

Richard Heathfield

unread,
Dec 30, 2006, 4:06:19 AM12/30/06
to
jacob navia said:

> Dave Vandervies a écrit :
>>
>> If knowing the length of strings is that important, can you explain
>> how counted strings would have made this code easier to write, clearer,
>> or less error-prone?
>>
>>
>> /* -8<--Code starts here--8<- */
>> #include <assert.h>
>> #include <ctype.h>
>> #include <string.h>
>>
>> int unpack_nmea(char *sentence,char **fields, int nfields)
>> {
>> static char *hexdigits="0123456789ABCDEF";
>> int needed;
>> char *start,*ptr;
>> char cksum=0;
>> int i;
>>
>> ptr=start=strchr(sentence,'$');
> -------
> In the strchr call above, a counted strings implementation can
> safely replace a strchr with memchr, that doesn't check at each
> character the terminating zero but just makes a bounded
> memory scan

Whilst that *is* an improvement, it's a micro-optimisation, since each
character in turn is being examined anyway.

<snip>

> Here the string library provides
> Strfind_firstof(String, setOfChars);

*The* string library is the set of functions provided as part of any hosted
C implementation, and it doesn't supply any function of the name specified.
If you mean some third-party library of your own creation, you'd be wise to
specify this, to avoid confusion.

Incidentally, *THE* string library provides strcspn and strpbrk.

<snip>


>>
>> /*Now we can check whether the input is well-formed...*/
>> if(*ptr=='0')
> -------
> Are you sure you are testing for the character zero ('0') and
> not for the terminating zero ( 0 ) ?????????

A reasonable question. Watch what you're doing with all those question
marks, though...

<snip>

> ---------
> The counted strcspn version needs NOT to test for a terminating zero
> but just for the pattern being searched

Again, whilst this *is* an improvement, it is merely a micro-optimisation,
of little or no real consequence. It's not as if you're reducing the time
complexity of the algorithm.

> But I may disappoint you since in the implementation of lcc-win32 the
> strings are probably much slower than they ought to be since the
> main thrust of the package is to provide more security and not speed.
>
> I will start a faster version soon.
>
> As you can see, the main advantages are the obviating for the tests
> for the zero byte.

If that's the main advantage, you may as well throw it away, since it isn't
*enough* of an advantage to make it worth doing.

The main advantages of my own string library are:

1) it caches string lengths, thus allowing fast len, cat and cpy operations;
2) it resizes buffers when necessary, without troubling the user, and keeps
extra space around so that it doesn't need to go to the well every time;
3) it contains several useful string functions not provided by the standard
library;
4) it is written in ISO C and doesn't depend on any particular compiler
features.

The first of these has genuine and significant time complexity reduction
benefits. The second takes a load off the programmer's shoulders. The third
is basically a sack of nice toys. And the fourth is essential if the code
is to remain viable in the long term.

It is loading more messages.
0 new messages