f

#### Efficency and the standard library

```This may have gotten buried given that it started in a Nilges thread,
but it's actually pretty interesting.

There was some discussion of algorithms to perform the task:
Inputs:  target string, replacement string, original string
Output:  a newly-allocated string containing the original
string with each copy of the target string replaced with the
replacement string.

Here's a hunk of mine:

for (count = 0, t = strstr(target, in); t && *t; t = strstr(t, in)) {
++count;
t += inlen;
}

Here's a hunk of another one:

>     ptrIndex1 = strMaster;
>     while(*ptrIndex1)
>     {
>         ptrIndex0 = ptrIndex1;
>         while (-1)
>         {
>             for(;
>                 *ptrIndex1 && *ptrIndex1 != *strTarget;
>                 ptrIndex1++);
>             for(ptrIndex2 = strTarget, ptrIndex3 = ptrIndex1;
>                 *ptrIndex3
>                 &&
>                 *ptrIndex2
>                 &&
>                 *ptrIndex3 == *ptrIndex2;
>                 ptrIndex3++, ptrIndex2++);
>             if (!*ptrIndex2) break;
>             ptrIndex1 = ptrIndex3;
>             if (!*ptrIndex3) break;
>         }

These hunks are essentially performing the same part of the core loop;
find the next occurrence of the target string in the original string.

The second one was written by Edward Nilges ("spinoza1111").  He offers
in its defense the assertion that it's the "best" algorithm.  (Nevermind
that it's got a bug; the bug could be fixed easily.)

My thinking:

The first is better, not because it's less buggy (that could be fixed), but
because it's simpler to understand.  It may, or may not, be less efficient.
However, efficiency will vary widely with input characteristics; for some
cases, the arguable inefficiencies may be completely irrelevant, while in
others, they'd be significant.

But you should always write the simpler one first, and wait until you've
profiled the code and verified that there's a bottleneck, and you know where
it is, before trying to optimize.  You may, or may not, be able to outperform
a given library's implementation of strstr().  If you have unusual inputs,
you have a pretty good shot at it... But it may not be worth it.  The
complicated example has had at least one bug identified, and there may be
others.  It's extremely hard to read, partially because of the poor
naming, and partially because of the counter-idiomatic usage.  But mostly,
it's a lot more work to write and maintain, and for no known benefit.

It's good to think a little about efficiency, but write for clarity and
correctness first, so you have a known-working program to check your
results if you later need to modify it for speed.

-s
--
Copyright 2010, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
```
 0
usenet-nospam (2309)
2/10/2010 7:25:54 PM
comp.lang.c 30657 articles. 5 followers. spinoza1111 (3246) is leader.

640 Replies
2439 Views

Similar Articles

[PageSpeed] 32

```On Wed, 10 Feb 2010 19:25:54 +0000, Seebs wrote:

> This may have gotten buried given that it started in a Nilges thread,
> but it's actually pretty interesting.
>
> There was some discussion of algorithms to perform the task:
> 	Inputs:  target string, replacement string, original string Output:  a
> 	newly-allocated string containing the original
> 	  string with each copy of the target string replaced with the
> 	  replacement string.
>
> Here's a hunk of mine:
>
>         for (count = 0, t = strstr(target, in); t && *t; t = strstr(t,
>         in)) {
>                 ++count;
>                 t += inlen;
>         }
>

Of course yours is more readable.
Personally, I prefer not to use one letter variable names (three letter names are
more grepable, also for the eyes). Also I dont like for(;;) statements that are too wide
(and with repeating subexpressions). But it's all a matter of taste, of course.

I'd prefer:

for (count = 0, tmp=target; tmp = strstr(tmp, in); ) {
if ( !*tmp) break;
count++;
tmp += inlen;
...
}

My own strstr() loop:

nhit = 0;
for (tail = haystack; src = strstr(tail, needle); tail = src + needle_len) {
nhit++;
...
}

, which uses one variable too many, but that will be used later on.

AvK
```
 0
root32 (398)
2/10/2010 8:16:05 PM
```In article <slrnhn628c.o3u.usenet-nospam@guild.seebs.net>, usenet-
nospam@seebs.net says...
>
> This may have gotten buried given that it started in a Nilges thread,
> but it's actually pretty interesting.
>
> There was some discussion of algorithms to perform the task:
> 	Inputs:  target string, replacement string, original string
> 	Output:  a newly-allocated string containing the original
> 	  string with each copy of the target string replaced with the
> 	  replacement string.
>
> Here's a hunk of mine:
>
>         for (count = 0, t = strstr(target, in); t && *t; t = strstr(t, in)) {
>                 ++count;
>                 t += inlen;
>         }
>
> Here's a hunk of another one:
>
> >     ptrIndex1 = strMaster;
> >     while(*ptrIndex1)
> >     {
> >         ptrIndex0 = ptrIndex1;
> >         while (-1)
> >         {
> >             for(;
> >                 *ptrIndex1 && *ptrIndex1 != *strTarget;
> >                 ptrIndex1++);
> >             for(ptrIndex2 = strTarget, ptrIndex3 = ptrIndex1;
> >                 *ptrIndex3
> >                 &&
> >                 *ptrIndex2
> >                 &&
> >                 *ptrIndex3 == *ptrIndex2;
> >                 ptrIndex3++, ptrIndex2++);
> >             if (!*ptrIndex2) break;
> >             ptrIndex1 = ptrIndex3;
> >             if (!*ptrIndex3) break;
> >         }
>
> These hunks are essentially performing the same part of the core loop;
> find the next occurrence of the target string in the original string.
>
> The second one was written by Edward Nilges ("spinoza1111").  He offers
> in its defense the assertion that it's the "best" algorithm.  (Nevermind
> that it's got a bug; the bug could be fixed easily.)
>
> My thinking:
>
> The first is better, not because it's less buggy (that could be fixed), but

For a standard library, the *most* important thing is correctness.  IOW,
a bsearch() function that is blazing fast but fails if there are more
than 2 billion items is not as good as one that is only half as fast but
works with anything up to size_t (-1) number of elements.

Assuming correctness, then effeciency should be the next decider.  An
interesting project would be to take a collection of all public C
libraries and do the following:
1. Exhaustively test for correctness
2. Analyze for efficiency
3. Choose best of breed from the above analysis.  It could also be a
hybrid (e.g. a decider function chooses the best algorithm based on
conditions).

Here is a list of some compilers (most of these come with source code)
that could be used as a starting point:

Directory of c:\compiler
06/03/2009  11:38 AM    <DIR>          bscc
01/21/2010  04:16 PM    <DIR>          clang-2.6
01/21/2010  04:35 PM    <DIR>          commoncpp2-1.7.3
01/13/2010  01:13 PM    <DIR>          coreutils-8.4
10/16/2009  05:39 PM    <DIR>          ctool_2.12
10/16/2009  12:39 PM    <DIR>          fog
06/04/2009  11:52 AM    <DIR>          g95-0.92
06/04/2009  11:58 AM    <DIR>          gcc-4.4.0
10/16/2009  05:58 PM    <DIR>          gcc-4.4.2
01/21/2010  04:39 PM    <DIR>          gcc-4.4.3
10/16/2009  05:59 PM    <DIR>          lcc
10/16/2009  06:00 PM    <DIR>          llvm
01/21/2010  04:18 PM    <DIR>          llvm-2.6
01/21/2010  04:19 PM    <DIR>          llvm-gcc4.2-2.6.source
11/30/2008  08:00 AM    <DIR>          open64-4.2.1-0
10/16/2009  06:06 PM    <DIR>          OW18src
01/21/2010  04:18 PM    <DIR>          owdaily
06/04/2009  11:38 AM    <DIR>          tendra
01/21/2010  04:35 PM    <DIR>          ucommon-2.0.8
06/03/2009  02:49 PM    <DIR>          vmkit-0.25
06/03/2009  12:24 PM    <DIR>          watcom
01/21/2010  04:00 PM    <DIR>          x86_open64-4.2.3

```
 0
dcorbit (2697)
2/10/2010 8:54:41 PM
```Dann Corbit <dcorbit@connx.com> writes:

> For a standard library, the *most* important thing is correctness.  IOW,
> a bsearch() function that is blazing fast but fails if there are more
> than 2 billion items is not as good as one that is only half as fast but
> works with anything up to size_t (-1) number of elements.

If the former bsearch() implementation is on a system that
doesn't support more than 2 billion bytes of contiguous data, I'm
--
"The expression isn't unclear *at all* and only an expert could actually
--Dan Pop
```
 0
blp (3955)
2/10/2010 9:12:16 PM
```Ben Pfaff wrote:
> Dann Corbit <dcorbit@connx.com> writes:
>
>> For a standard library, the *most* important thing is correctness.  IOW,
>> a bsearch() function that is blazing fast but fails if there are more
>> than 2 billion items is not as good as one that is only half as fast but
>> works with anything up to size_t (-1) number of elements.
>
> If the former bsearch() implementation is on a system that
> doesn't support more than 2 billion bytes of contiguous data, I'm

Why?
--
```
 0
Phred4 (88)
2/11/2010 12:29:52 AM
```Phred Phungus <Phred@example.invalid> writes:

> Ben Pfaff wrote:
>> Dann Corbit <dcorbit@connx.com> writes:
>>
>>> For a standard library, the *most* important thing is correctness.
>>> IOW, a bsearch() function that is blazing fast but fails if there
>>> are more than 2 billion items is not as good as one that is only
>>> half as fast but works with anything up to size_t (-1) number of
>>> elements.
>>
>> If the former bsearch() implementation is on a system that
>> doesn't support more than 2 billion bytes of contiguous data, I'm
>
> Why?

Because the bsearch() function cannot exceed a limit of 2 billion
items on an implementation that limits objects to 2 billion bytes
or less.
--
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}
```
 0
blp (3955)
2/11/2010 12:37:13 AM
```Seebs <usenet-nospam@seebs.net> writes:

> This may have gotten buried given that it started in a Nilges thread,
> but it's actually pretty interesting.
>
> There was some discussion of algorithms to perform the task:
> 	Inputs:  target string, replacement string, original string
> 	Output:  a newly-allocated string containing the original
> 	  string with each copy of the target string replaced with the
> 	  replacement string.
>
> Here's a hunk of mine:
>
>         for (count = 0, t = strstr(target, in); t && *t; t = strstr(t, in)) {
>                 ++count;
>                 t += inlen;
>         }
>
> Here's a hunk of another one:
>
>>     ptrIndex1 = strMaster;
>>     while(*ptrIndex1)
>>     {
>>         ptrIndex0 = ptrIndex1;
>>         while (-1)
>>         {
>>             for(;
>>                 *ptrIndex1 && *ptrIndex1 != *strTarget;
>>                 ptrIndex1++);
>>             for(ptrIndex2 = strTarget, ptrIndex3 = ptrIndex1;
>>                 *ptrIndex3
>>                 &&
>>                 *ptrIndex2
>>                 &&
>>                 *ptrIndex3 == *ptrIndex2;
>>                 ptrIndex3++, ptrIndex2++);
>>             if (!*ptrIndex2) break;
>>             ptrIndex1 = ptrIndex3;
>>             if (!*ptrIndex3) break;
>>         }
>
> These hunks are essentially performing the same part of the core loop;
> find the next occurrence of the target string in the original string.
>
> The second one was written by Edward Nilges ("spinoza1111").  He offers
> in its defense the assertion that it's the "best" algorithm.  (Nevermind
> that it's got a bug; the bug could be fixed easily.)
>
> My thinking:
>
> The first is better, not because it's less buggy (that could be fixed), but
> because it's simpler to understand.  It may, or may not, be less efficient.
> However, efficiency will vary widely with input characteristics; for some
> cases, the arguable inefficiencies may be completely irrelevant, while in
> others, they'd be significant.

I don't think you can dismiss the bugs so easily.  I would argue that
it is not a coincidence that the more complex code has more bugs.  I
can't write code that looks like spinoza1111's code and get it right.
I *have* to write simpler code, broken into simple functions, or I have
no chance of getting it to be correct.

For example, the latest improvement introduced another bug[1] and I
don't think that is simple carelessness.  Without a re-write I suspect
almost any change is as likely to introduce a bug as fix one (I tried
to see where the error was, but I gave up).  If I was paid to fix it,
I'd simply start again and it would end a up as I have already posted,
though to mirror the behaviour I'd now have to add some argument
checking.

<snip>

[1] Apparently when the target string is not present in the source
string: e.g. replace("a", "x", "b").

--
Ben.
```
 0
ben.usenet (6790)
2/11/2010 1:05:27 AM
```In article <87ocjwobeu.fsf@blp.benpfaff.org>, blp@cs.stanford.edu
says...
>
> Phred Phungus <Phred@example.invalid> writes:
>
> > Ben Pfaff wrote:
> >> Dann Corbit <dcorbit@connx.com> writes:
> >>
> >>> For a standard library, the *most* important thing is correctness.
> >>> IOW, a bsearch() function that is blazing fast but fails if there
> >>> are more than 2 billion items is not as good as one that is only
> >>> half as fast but works with anything up to size_t (-1) number of
> >>> elements.
> >>
> >> If the former bsearch() implementation is on a system that
> >> doesn't support more than 2 billion bytes of contiguous data, I'm
> >> not worried about it.
> >
> > Why?
>
> Because the bsearch() function cannot exceed a limit of 2 billion
> items on an implementation that limits objects to 2 billion bytes
> or less.

If we are talking about constructing a best of breed library system for
the C language, then the distinction is of enormous importance.

While I agree it is not relevant for the original implementation, it is
for an implementation where we are trying to pick and choose the best
possible routines.

P.S.
The former case is still a bug waiting to happen.

Even if the former implementation is a toaster IC, 40 years in the
future, our toaster ICs will have 50 GB RAM on board.
```
 0
dcorbit (2697)
2/11/2010 1:18:49 AM
```On 2010-02-11, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
> I don't think you can dismiss the bugs so easily.  I would argue that
> it is not a coincidence that the more complex code has more bugs.  I
> can't write code that looks like spinoza1111's code and get it right.
> I *have* to write simpler code, broken into simple functions, or I have
> no chance of getting it to be correct.

You may be right on this.  Certainly, this kind of thing is one of the
major reasons that I sometimes rewrite things a few times until I am
sure I can understand the logic just by looking at it.  If I have to
think it through, usually that means something is wrong, or the problem
is extremely hard.

> For example, the latest improvement introduced another bug[1] and I
> don't think that is simple carelessness.  Without a re-write I suspect
> almost any change is as likely to introduce a bug as fix one (I tried
> to see where the error was, but I gave up).  If I was paid to fix it,
> I'd simply start again and it would end a up as I have already posted,
> though to mirror the behaviour I'd now have to add some argument
> checking.

I think it would be interesting to start from his code and see whether it
can be fixed by cleanups and refactoring.  I bet it could, although it'd
certainly take longer than just writing one from scratch.

But, e.g., starting by using names a little better than "ptrIndex1" and
the like would make it a ton simpler.

-s
--
Copyright 2010, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
```
 0
usenet-nospam (2309)
2/11/2010 1:46:29 AM
```Seebs <usenet-nos...@seebs.net> wrote:
> There was some discussion of algorithms to perform the task:
> =A0 Inputs: =A0target string, replacement string, original string
> =A0 Output: =A0a newly-allocated string containing the original
> =A0    =A0 =A0 =A0 string with each copy of the target string replaced
>            with the replacement string.
>
> Here's a hunk of mine:
>
> =A0 for (count =3D 0, t =3D strstr(target, in); t && *t;
> t =3D strstr(t, in)) {

Why are you seemingly scanning the target string for occurances
of 'in', which I would presume to be original 'input' string?

> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ++count;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 t +=3D inlen;
> =A0 =A0 =A0 =A0 }

What if the string being scanned for is empty? If the string
to be scanned is non-empty, this will produce an infinite loop.

--
Peter
```
 0
airia (1802)
2/11/2010 2:07:59 AM
```On 2010-02-11, Peter Nilsson <airia@acay.com.au> wrote:
>> � for (count = 0, t = strstr(target, in); t && *t;
>> t = strstr(t, in)) {

> Why are you seemingly scanning the target string for occurances
> of 'in', which I would presume to be original 'input' string?

"in", "out", "original".

> What if the string being scanned for is empty? If the string
> to be scanned is non-empty, this will produce an infinite loop.

This was indeed observed, which is why the error checking at the
beginning of the function is now modified to reject a 0-length
thing-to-replace.

-s
--
Copyright 2010, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
```
 0
usenet-nospam (2309)
2/11/2010 2:30:23 AM
```On 2/10/2010 9:30 PM, Seebs wrote:
> On 2010-02-11, Peter Nilsson<airia@acay.com.au>  wrote:
>>>    for (count = 0, t = strstr(target, in); t&&  *t;
>>> t = strstr(t, in)) {
>
>> Why are you seemingly scanning the target string for occurances
>> of 'in', which I would presume to be original 'input' string?
>
> "in", "out", "original".
>
>> What if the string being scanned for is empty? If the string
>> to be scanned is non-empty, this will produce an infinite loop.
>
> This was indeed observed, which is why the error checking at the
> beginning of the function is now modified to reject a 0-length
> thing-to-replace.

... which is what I imagined the `*t' test in your fragment
was supposed to catch.  If zero-length targets are rejected
earlier, I'm somehow missing the purpose of the `*t'.

--
Eric Sosman
esosman@ieee-dot-org.invalid
```
 0
esosman2 (3096)
2/11/2010 2:46:41 AM
```Dann Corbit wrote:
> In article <87ocjwobeu.fsf@blp.benpfaff.org>, blp@cs.stanford.edu
> says...
>> Phred Phungus <Phred@example.invalid> writes:
>>
>>> Ben Pfaff wrote:
>>>> Dann Corbit <dcorbit@connx.com> writes:
>>>>
>>>>> For a standard library, the *most* important thing is correctness.
>>>>> IOW, a bsearch() function that is blazing fast but fails if there
>>>>> are more than 2 billion items is not as good as one that is only
>>>>> half as fast but works with anything up to size_t (-1) number of
>>>>> elements.
>>>> If the former bsearch() implementation is on a system that
>>>> doesn't support more than 2 billion bytes of contiguous data, I'm
>>> Why?
>> Because the bsearch() function cannot exceed a limit of 2 billion
>> items on an implementation that limits objects to 2 billion bytes
>> or less.
>
>
> If we are talking about constructing a best of breed library system for
> the C language, then the distinction is of enormous importance.
>
> While I agree it is not relevant for the original implementation, it is
> for an implementation where we are trying to pick and choose the best
> possible routines.
>
> P.S.
> The former case is still a bug waiting to happen.
>
> Even if the former implementation is a toaster IC, 40 years in the
> future, our toaster ICs will have 50 GB RAM on board.

That's a lot of computer power for something that requires almost none.
--
fred
```
 0
Phred4 (88)
2/11/2010 5:34:56 AM
```Seebs <usenet-nospam@seebs.net> writes:

> This may have gotten buried given that it started in a Nilges thread,
> but it's actually pretty interesting.
>
> There was some discussion of algorithms to perform the task:
> 	Inputs:  target string, replacement string, original string
> 	Output:  a newly-allocated string containing the original
> 	  string with each copy of the target string replaced with the
> 	  replacement string.
>
> Here's a hunk of mine:
>
>         for (count = 0, t = strstr(target, in); t && *t; t = strstr(t, in)) {
>                 ++count;
>                 t += inlen;
>         }
>
> Here's a hunk of another one:
>
>>     ptrIndex1 = strMaster;
>>     while(*ptrIndex1)
>>     {
>>         ptrIndex0 = ptrIndex1;
>>         while (-1)
>>         {
>>             for(;
>>                 *ptrIndex1 && *ptrIndex1 != *strTarget;
>>                 ptrIndex1++);
>>             for(ptrIndex2 = strTarget, ptrIndex3 = ptrIndex1;
>>                 *ptrIndex3
>>                 &&
>>                 *ptrIndex2
>>                 &&
>>                 *ptrIndex3 == *ptrIndex2;
>>                 ptrIndex3++, ptrIndex2++);
>>             if (!*ptrIndex2) break;
>>             ptrIndex1 = ptrIndex3;
>>             if (!*ptrIndex3) break;
>>         }
>
> These hunks are essentially performing the same part of the core loop;
> find the next occurrence of the target string in the original string.
>
> The second one was written by Edward Nilges ("spinoza1111").  He offers
> in its defense the assertion that it's the "best" algorithm.  (Nevermind
> that it's got a bug; the bug could be fixed easily.)
>
> My thinking:
>
> The first is better, not because it's less buggy (that could be fixed), but
> because it's simpler to understand.  It may, or may not, be less
> efficient.

Total nonsense.

The better one is the one that runs more efficiently and works. So assuming
the bug ix fixed and its more efficient then other is better. Its called
a function. You dont need to know whats in it.
```
 0
rgrdev_ (1097)
2/11/2010 6:52:21 AM
```"Dann Corbit" <dcorbit@connx.com> ha scritto nel messaggio
news:MPG.25dcbceb389a23e59896c8@news.eternal-september.org...
> In article <slrnhn628c.o3u.usenet-nospam@guild.seebs.net>, usenet-
> nospam@seebs.net says...
>>
>> This may have gotten buried given that it started in a Nilges thread,
>> but it's actually pretty interesting.
>>
>> There was some discussion of algorithms to perform the task:
>> Inputs:  target string, replacement string, original string
>> Output:  a newly-allocated string containing the original
>>   string with each copy of the target string replaced with the
>>   replacement string.
>>
>> Here's a hunk of mine:
>>
>>         for (count = 0, t = strstr(target, in); t && *t; t = strstr(t, in)) {
>>                 ++count;
>>                 t += inlen;
>>         }
>>
>> Here's a hunk of another one:
>>
>> >     ptrIndex1 = strMaster;
>> >     while(*ptrIndex1)
>> >     {
>> >         ptrIndex0 = ptrIndex1;
>> >         while (-1)
>> >         {
>> >             for(;
>> >                 *ptrIndex1 && *ptrIndex1 != *strTarget;
>> >                 ptrIndex1++);
>> >             for(ptrIndex2 = strTarget, ptrIndex3 = ptrIndex1;
>> >                 *ptrIndex3
>> >                 &&
>> >                 *ptrIndex2
>> >                 &&
>> >                 *ptrIndex3 == *ptrIndex2;
>> >                 ptrIndex3++, ptrIndex2++);
>> >             if (!*ptrIndex2) break;
>> >             ptrIndex1 = ptrIndex3;
>> >             if (!*ptrIndex3) break;
>> >         }
>>
>> These hunks are essentially performing the same part of the core loop;
>> find the next occurrence of the target string in the original string.
>>
>> The second one was written by Edward Nilges ("spinoza1111").  He offers
>> in its defense the assertion that it's the "best" algorithm.  (Nevermind
>> that it's got a bug; the bug could be fixed easily.)
>>
>> My thinking:
>>
>> The first is better, not because it's less buggy (that could be fixed), but
>
> For a standard library, the *most* important thing is correctness.  IOW,

for a standard library function
the *most* important thing is the easy to use
and the error handling well think

bugs could be detect and correct
one indeciprable assembly for a miracle
can be correct and run well

but for the not the easy to use
and the poor hadling of errors
all you have no way of correct them

```
 0
io_x
2/11/2010 8:09:21 AM
```Richard wrote:
> Total nonsense.
>
> The better one is the one that runs more efficiently and works. So
> assuming the bug ix fixed and its more efficient then other is
> better. Its called a function. You dont need to know whats in it.

The one who will maintain this and other functions, needs to know what's in
it.

--
Mark

```
 0
2/11/2010 8:37:40 AM
```On 11 Feb, 01:05, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
> Seebs <usenet-nos...@seebs.net> writes:

> > This may have gotten buried given that it started in a Nilges thread,
> > but it's actually pretty interesting.
>
> > There was some discussion of algorithms to perform the task:
> > =A0 =A0Inputs: =A0target string, replacement string, original string
> > =A0 =A0Output: =A0a newly-allocated string containing the original
> > =A0 =A0 =A0string with each copy of the target string replaced with the
> > =A0 =A0 =A0replacement string.
>
> > Here's a hunk of mine:
>
> > =A0 =A0 =A0 =A0 for (count =3D 0, t =3D strstr(target, in); t && *t; t =
=3D strstr(t, in)) {
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ++count;
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 t +=3D inlen;
> > =A0 =A0 =A0 =A0 }
>
> > Here's a hunk of another one:
>
> >> =A0 =A0 ptrIndex1 =3D strMaster;
> >> =A0 =A0 while(*ptrIndex1)
> >> =A0 =A0 {
> >> =A0 =A0 =A0 =A0 ptrIndex0 =3D ptrIndex1;
> >> =A0 =A0 =A0 =A0 while (-1)
> >> =A0 =A0 =A0 =A0 {
> >> =A0 =A0 =A0 =A0 =A0 =A0 for(;
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex1 && *ptrIndex1 !=3D *strTarg=
et;
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ptrIndex1++);
> >> =A0 =A0 =A0 =A0 =A0 =A0 for(ptrIndex2 =3D strTarget, ptrIndex3 =3D ptr=
Index1;
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex3
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 &&
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex2
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 &&
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex3 =3D=3D *ptrIndex2;
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ptrIndex3++, ptrIndex2++);
> >> =A0 =A0 =A0 =A0 =A0 =A0 if (!*ptrIndex2) break;
> >> =A0 =A0 =A0 =A0 =A0 =A0 ptrIndex1 =3D ptrIndex3;
> >> =A0 =A0 =A0 =A0 =A0 =A0 if (!*ptrIndex3) break;
> >> =A0 =A0 =A0 =A0 }
>
> > These hunks are essentially performing the same part of the core loop;
> > find the next occurrence of the target string in the original string.
>
> > The second one was written by Edward Nilges ("spinoza1111"). =A0He offe=
rs
> > in its defense the assertion that it's the "best" algorithm. =A0(Neverm=
ind
> > that it's got a bug; the bug could be fixed easily.)
>
> > My thinking:
>
> > The first is better, not because it's less buggy (that could be fixed),=
but
> > because it's simpler to understand. =A0It may, or may not, be less effi=
cient.
> > However, efficiency will vary widely with input characteristics; for so=
me
> > cases, the arguable inefficiencies may be completely irrelevant, while =
in
> > others, they'd be significant.
>
> I don't think you can dismiss the bugs so easily. =A0I would argue that
> it is not a coincidence that the more complex code has more bugs. =A0I
> can't write code that looks like spinoza1111's code and get it right.
> I *have* to write simpler code, broken into simple functions, or I have
> no chance of getting it to be correct.

"I now suggest that we confine ourselves to the design and
implementation of intellectually manageable programs." Dijkstra

> For example, the latest improvement introduced another bug[1] and I
> don't think that is simple carelessness. =A0Without a re-write I suspect
> almost any change is as likely to introduce a bug as fix one (I tried
> to see where the error was, but I gave up). =A0If I was paid to fix it,
> I'd simply start again and it would end a up as I have already posted,
> though to mirror the behaviour I'd now have to add some argument
> checking.
>
> <snip>
>
> [1] Apparently when the target string is not present in the source
> string: e.g. replace("a", "x", "b").
```
 0
2/11/2010 9:01:16 AM
```On 10 Feb, 19:25, Seebs <usenet-nos...@seebs.net> wrote:

> This may have gotten buried given that it started in a Nilges thread,
> but it's actually pretty interesting.
>
> There was some discussion of algorithms to perform the task:
> =A0 =A0 =A0 =A0 Inputs: =A0target string, replacement string, original st=
ring
> =A0 =A0 =A0 =A0 Output: =A0a newly-allocated string containing the origin=
al
> =A0 =A0 =A0 =A0 =A0 string with each copy of the target string replaced w=
ith the
> =A0 =A0 =A0 =A0 =A0 replacement string.
>
> Here's a hunk of mine:
>
> =A0 =A0 =A0 =A0 for (count =3D 0, t =3D strstr(target, in); t && *t; t =
=3D strstr(t, in)) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ++count;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 t +=3D inlen;
> =A0 =A0 =A0 =A0 }
>
> Here's a hunk of another one:
>
> > =A0 =A0 ptrIndex1 =3D strMaster;
> > =A0 =A0 while(*ptrIndex1)
> > =A0 =A0 {
> > =A0 =A0 =A0 =A0 ptrIndex0 =3D ptrIndex1;
> > =A0 =A0 =A0 =A0 while (-1)
> > =A0 =A0 =A0 =A0 {
> > =A0 =A0 =A0 =A0 =A0 =A0 for(;
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex1 && *ptrIndex1 !=3D *strTarge=
t;
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ptrIndex1++);
> > =A0 =A0 =A0 =A0 =A0 =A0 for(ptrIndex2 =3D strTarget, ptrIndex3 =3D ptrI=
ndex1;
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex3
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 &&
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex2
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 &&
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex3 =3D=3D *ptrIndex2;
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ptrIndex3++, ptrIndex2++);
> > =A0 =A0 =A0 =A0 =A0 =A0 if (!*ptrIndex2) break;
> > =A0 =A0 =A0 =A0 =A0 =A0 ptrIndex1 =3D ptrIndex3;
> > =A0 =A0 =A0 =A0 =A0 =A0 if (!*ptrIndex3) break;
> > =A0 =A0 =A0 =A0 }
>
> These hunks are essentially performing the same part of the core loop;
> find the next occurrence of the target string in the original string.
>
> The second one was written by Edward Nilges ("spinoza1111"). =A0He offers
> in its defense the assertion that it's the "best" algorithm. =A0(Nevermin=
d
> that it's got a bug; the bug could be fixed easily.)
>
> My thinking:
>
> The first is better, not because it's less buggy (that could be fixed), b=
ut
> because it's simpler to understand. =A0It may, or may not, be less effici=
ent.
> However, efficiency will vary widely with input characteristics; for some
> cases, the arguable inefficiencies may be completely irrelevant, while in
> others, they'd be significant.
>
> But you should always write the simpler one first, and wait until you've
> profiled the code and verified that there's a bottleneck, and you know wh=
ere
> it is, before trying to optimize. =A0You may, or may not, be able to outp=
erform
> a given library's implementation of strstr(). =A0If you have unusual inpu=
ts,
> you have a pretty good shot at it... But it may not be worth it. =A0The
> complicated example has had at least one bug identified, and there may be
> others. =A0It's extremely hard to read, partially because of the poor
> naming, and partially because of the counter-idiomatic usage. =A0But most=
ly,
> it's a lot more work to write and maintain, and for no known benefit.
>
> It's good to think a little about efficiency, but write for clarity and
> correctness first, so you have a known-working program to check your
> results if you later need to modify it for speed.

yes. If strstr() didn't exist it would be necessary to invent it. The
use of appropriate abstractions simplifies the code.

lists of memory blocks. Queues were linked lists of messages. Since
the same pointers were used for both purposes a queue was also a list
of memory blocks.

The code needed to free (return to a free list) all the memory blocks
of the messages that came before a particular message type. Two pages
of tangled code needed to find the block before the first block of the
target message followed by direct manipulation of queue head and tail
pointer and the free list pointer. The blocks also had to be marked as
free (they had some associated data). After I found my third bug I
wrote:

while (not empty (queue) and queue_head.message_type !=3D target)
{
msg =3D remove_msg (queue)
free_msg (msg)
}

(pseudo code)

As my version was shorter, simpler and more correct it was adopted.
Why deal with three things at once when it can be delegated else
where? The code wanted to manipulate messages not memory blocks.
```
 0
2/11/2010 9:12:59 AM
```On 11 Feb, 06:52, Richard <rgrd...@gmail.com> wrote:
> Seebs <usenet-nos...@seebs.net> writes:

> > There was some discussion of algorithms to perform [some] task:

[simple code]

and

[complex code]

<snip>

> > The first is better, not because it's less buggy (that could be fixed),=
but
> > because it's simpler to understand. =A0It may, or may not, be less
> > efficient.
>
> Total nonsense.
>
> The better one is the one that runs more efficiently and works.

how do we demonstrate that it works?

> So assuming
> the bug ix fixed and its more efficient then other is better. Its called
> a function. You dont need to know whats in it.

"There are two ways of  constructing a software design:  One way is to
make it so  simple that there are  obviously no deficiencies,  and the
other   way is to make it   so complicated that   there are no obvious
deficiencies.  The first method is far more difficult."
-- C.A.R. Hoare
```
 0
2/11/2010 9:17:24 AM
```In article <slrnhn628c.o3u.usenet-nospam@guild.seebs.net>,
Seebs  <usenet-nospam@seebs.net> wrote:

>But you should always write the simpler one first, and wait until you've
>profiled the code and verified that there's a bottleneck, and you know where
>it is, before trying to optimize.

But wouldn't that be Extreme Programming?

-- Richard
--
Please remember to mention me / in tapes you leave behind.
```
 0
richard91 (3692)
2/11/2010 12:47:32 PM
```On 2010-02-11, Richard Tobin <richard@cogsci.ed.ac.uk> wrote:
> In article <slrnhn628c.o3u.usenet-nospam@guild.seebs.net>,
> Seebs  <usenet-nospam@seebs.net> wrote:
>>But you should always write the simpler one first, and wait until you've
>>profiled the code and verified that there's a bottleneck, and you know where
>>it is, before trying to optimize.

> But wouldn't that be Extreme Programming?

Only if you have two people do it at once, I think?  :)

-s
--
Copyright 2010, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
```
 0
usenet-nospam (2309)
2/11/2010 1:58:16 PM
```On Feb 11, 2:09=A0am, "io_x" <a...@b.c.invalid> wrote:
> "Dann Corbit" <dcor...@connx.com> ha scritto nel messaggionews:MPG.25dcbc=
eb389a23e59896c8@news.eternal-september.org...
>

[snip]

>
> > For a standard library, the *most* important thing is correctness. =A0I=
OW,
>
> for a standard library function
> the *most* important thing is the easy to use
> and the error handling well think
>

It doesn't matter how easy to it is to use if it gives you the wrong
It doesn't matter how well it handles errors if it gives you the wrong
It doesn't matter how fast it is if it gives you the wrong answer.
It doesn't matter how much memory it uses if it gives you the wrong

Correctness comes first.  Then we can argue about everything else.
```
 0
jfbode1029 (228)
2/11/2010 3:22:59 PM
```In article <367d44ff-3e74-464c-a816-e8280fb262e6
>
> On Feb 11, 2:09�am, "io_x" <a...@b.c.invalid> wrote:
> > "Dann Corbit" <dcor...@connx.com> ha scritto nel messaggionews:MPG.25dcbceb389a23e59896c8@news.eternal-september.org...
> >
>
> [snip]
>
> >
> > > For a standard library, the *most* important thing is correctness. �IOW,
> >
> > for a standard library function
> > the *most* important thing is the easy to use
> > and the error handling well think
> >
>
> It doesn't matter how easy to it is to use if it gives you the wrong
> It doesn't matter how well it handles errors if it gives you the wrong
> It doesn't matter how fast it is if it gives you the wrong answer.
> It doesn't matter how much memory it uses if it gives you the wrong
>
> Correctness comes first.  Then we can argue about everything else.

Besides which, we don't get to change ease of use.  The interface and

```
 0
dcorbit (2697)
2/11/2010 7:49:56 PM
```"John Bode" <jfbode1029@gmail.com> ha scritto nel messaggio
On Feb 11, 2:09 am, "io_x" <a...@b.c.invalid> wrote:
> "Dann Corbit" <dcor...@connx.com> ha scritto nel
> messaggionews:MPG.25dcbceb389a23e59896c8@news.eternal-september.org...
>

[snip]

>
> > For a standard library, the *most* important thing is correctness. IOW,
>
> for a standard library function
> the *most* important thing is the easy to use
> and the error handling well think
>

It doesn't matter how easy to it is to use if it gives you the wrong
It doesn't matter how well it handles errors if it gives you the wrong
It doesn't matter how fast it is if it gives you the wrong answer.
It doesn't matter how much memory it uses if it gives you the wrong

Correctness comes first.  Then we can argue about everything else.

#first is the idea that is good (and make all easy)
#after correct pariticulars (like litte bugs etc)

```
 0
io_x
2/11/2010 8:02:15 PM
```"Nick Keighley" <nick_keighley_nospam@hotmail.com> ha scritto nel messaggio
On 11 Feb, 01:05, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
> Seebs <usenet-nos...@seebs.net> writes:

> I don't think you can dismiss the bugs so easily. I would argue that
> it is not a coincidence that the more complex code has more bugs. I
> can't write code that looks like spinoza1111's code and get it right.
> I *have* to write simpler code, broken into simple functions, or I have
> no chance of getting it to be correct.

"I now suggest that we confine ourselves to the design and
implementation of intellectually manageable programs." Dijkstra

#yes that is the way
#that i not follow

> For example, the latest improvement introduced another bug[1] and I
> don't think that is simple carelessness. Without a re-write I suspect
> almost any change is as likely to introduce a bug as fix one (I tried
> to see where the error was, but I gave up). If I was paid to fix it,
> I'd simply start again and it would end a up as I have already posted,
> though to mirror the behaviour I'd now have to add some argument
> checking.
>
> <snip>
>
> [1] Apparently when the target string is not present in the source
> string: e.g. replace("a", "x", "b").

```
 0
io_x
2/11/2010 8:08:58 PM
```"Nick Keighley" <nick_keighley_nospam@hotmail.com> ha scritto nel messaggio
On 11 Feb, 01:05, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
> Seebs <usenet-nos...@seebs.net> writes:

> I don't think you can dismiss the bugs so easily. I would argue that
> it is not a coincidence that the more complex code has more bugs. I
> can't write code that looks like spinoza1111's code and get it right.
> I *have* to write simpler code, broken into simple functions, or I have
> no chance of getting it to be correct.

"I now suggest that we confine ourselves to the design and
implementation of intellectually manageable programs." Dijkstra

#yes that is the way
#that i not follow: possible i write code because i like miracles

> For example, the latest improvement introduced another bug[1] and I
> don't think that is simple carelessness. Without a re-write I suspect
> almost any change is as likely to introduce a bug as fix one (I tried
> to see where the error was, but I gave up). If I was paid to fix it,
> I'd simply start again and it would end a up as I have already posted,
> though to mirror the behaviour I'd now have to add some argument
> checking.
>
> <snip>
>
> [1] Apparently when the target string is not present in the source
> string: e.g. replace("a", "x", "b").

```
 0
io_x
2/11/2010 8:10:27 PM
```On Feb 11, 2:47=A0pm, rich...@cogsci.ed.ac.uk (Richard Tobin) wrote:
> In article <slrnhn628c.o3u.usenet-nos...@guild.seebs.net>,
>
> Seebs =A0<usenet-nos...@seebs.net> wrote:
> >But you should always write the simpler one first, and wait until you've
> >profiled the code and verified that there's a bottleneck, and you know w=
here
> >it is, before trying to optimize.
>
> But wouldn't that be Extreme Programming?
>
n)

```
 0
2/12/2010 9:53:12 AM
```"io_x" <a@b.c.invalid> ha scritto nel messaggio
>
> "Nick Keighley" <nick_keighley_nospam@hotmail.com> ha scritto nel messaggio
> On 11 Feb, 01:05, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
>> Seebs <usenet-nos...@seebs.net> writes:
>
>> I don't think you can dismiss the bugs so easily. I would argue that
>> it is not a coincidence that the more complex code has more bugs. I
>> can't write code that looks like spinoza1111's code and get it right.
>> I *have* to write simpler code, broken into simple functions, or I have
>> no chance of getting it to be correct.
>
> "I now suggest that we confine ourselves to the design and
> implementation of intellectually manageable programs." Dijkstra
>
> #yes that is the way
> #that i not follow: possible i write code because i like miracles

#yes i follow it but not every times

```
 0
io_x
2/12/2010 3:11:01 PM
```On Feb 11, 3:25=A0am, Seebs <usenet-nos...@seebs.net> wrote:
> This may have gotten buried given that it started in a Nilges thread,
> but it's actually pretty interesting.
>
> There was some discussion of algorithms to perform the task:
> =A0 =A0 =A0 =A0 Inputs: =A0target string, replacement string, original st=
ring
> =A0 =A0 =A0 =A0 Output: =A0a newly-allocated string containing the origin=
al
> =A0 =A0 =A0 =A0 =A0 string with each copy of the target string replaced w=
ith the
> =A0 =A0 =A0 =A0 =A0 replacement string.
>
> Here's a hunk of mine:
>
> =A0 =A0 =A0 =A0 for (count =3D 0, t =3D strstr(target, in); t && *t; t =
=3D strstr(t, in)) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ++count;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 t +=3D inlen;
> =A0 =A0 =A0 =A0 }
>
> Here's a hunk of another one:
>
>
>
>
>
> > =A0 =A0 ptrIndex1 =3D strMaster;
> > =A0 =A0 while(*ptrIndex1)
> > =A0 =A0 {
> > =A0 =A0 =A0 =A0 ptrIndex0 =3D ptrIndex1;
> > =A0 =A0 =A0 =A0 while (-1)
> > =A0 =A0 =A0 =A0 {
> > =A0 =A0 =A0 =A0 =A0 =A0 for(;
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex1 && *ptrIndex1 !=3D *strTarge=
t;
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ptrIndex1++);
> > =A0 =A0 =A0 =A0 =A0 =A0 for(ptrIndex2 =3D strTarget, ptrIndex3 =3D ptrI=
ndex1;
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex3
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 &&
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex2
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 &&
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex3 =3D=3D *ptrIndex2;
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ptrIndex3++, ptrIndex2++);
> > =A0 =A0 =A0 =A0 =A0 =A0 if (!*ptrIndex2) break;
> > =A0 =A0 =A0 =A0 =A0 =A0 ptrIndex1 =3D ptrIndex3;
> > =A0 =A0 =A0 =A0 =A0 =A0 if (!*ptrIndex3) break;
> > =A0 =A0 =A0 =A0 }
>
> These hunks are essentially performing the same part of the core loop;
> find the next occurrence of the target string in the original string.
>
> The second one was written by Edward Nilges ("spinoza1111"). =A0He offers
> in its defense the assertion that it's the "best" algorithm. =A0(Nevermin=
d
> that it's got a bug; the bug could be fixed easily.)

Don't lie, and don't try to bring me down to your low level. When you
posted this code, the bug had been fixed.

You are incredibly dishonest. You were dishonest when you advanced
your career by trying to destroy Herb Schildt, and here, on Feb 11,
you posted an OLD version of the code that contained the bug that that
the search is resumed after the end of the partial match, missing
overlapping strings.

I found, reported and fixed this bug on Feb 10 and on that date you
code improvement that works based on insight provided by the bug:
taking the first occurrence of the handle after the start of a partial
match as the restart point.

You have dishonestly presented the above code as my latest version in
order to dishonestly recover your reputation for competence, but you
are both incompetent and dishonest.
>
> My thinking:
>
> The first is better, not because it's less buggy (that could be fixed), b=
ut

You continually post solutions with bugs: you do not fix your crap:
and yet you have the nerve to disrespect others based on their bugs.

> because it's simpler to understand. =A0It may, or may not, be less effici=
ent.
> However, efficiency will vary widely with input characteristics; for some
> cases, the arguable inefficiencies may be completely irrelevant, while in
> others, they'd be significant.
>
> But you should always write the simpler one first, and wait until you've
> profiled the code and verified that there's a bottleneck, and you know wh=
ere
> it is, before trying to optimize. =A0You may, or may not, be able to outp=
erform
> a given library's implementation of strstr(). =A0If you have unusual inpu=
ts,
> you have a pretty good shot at it... But it may not be worth it. =A0The
> complicated example has had at least one bug identified, and there may be
> others. =A0It's extremely hard to read, partially because of the poor
> naming, and partially because of the counter-idiomatic usage. =A0But most=
ly,
> it's a lot more work to write and maintain, and for no known benefit.
>
> It's good to think a little about efficiency, but write for clarity and
> correctness first, so you have a known-working program to check your
> results if you later need to modify it for speed.

But: your code, as you concede, isn't working!

What a jerk!
>
> -s
> --
> Copyright 2010, all wrongs reversed. =A0Peter Seebach / usenet-nos...@see=
bs.nethttp://www.seebs.net/log/<-- lawsuits, religion, and funny picturesht=
tp://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!

```
 0
spinoza1111 (3246)
2/12/2010 5:00:26 PM
```On Feb 11, 9:05=A0am, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
> Seebs <usenet-nos...@seebs.net> writes:
> > This may have gotten buried given that it started in a Nilges thread,
> > but it's actually pretty interesting.
>
> > There was some discussion of algorithms to perform the task:
> > =A0 =A0Inputs: =A0target string, replacement string, original string
> > =A0 =A0Output: =A0a newly-allocated string containing the original
> > =A0 =A0 =A0string with each copy of the target string replaced with the
> > =A0 =A0 =A0replacement string.
>
> > Here's a hunk of mine:
>
> > =A0 =A0 =A0 =A0 for (count =3D 0, t =3D strstr(target, in); t && *t; t =
=3D strstr(t, in)) {
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ++count;
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 t +=3D inlen;
> > =A0 =A0 =A0 =A0 }
>
> > Here's a hunk of another one:
>
> >> =A0 =A0 ptrIndex1 =3D strMaster;
> >> =A0 =A0 while(*ptrIndex1)
> >> =A0 =A0 {
> >> =A0 =A0 =A0 =A0 ptrIndex0 =3D ptrIndex1;
> >> =A0 =A0 =A0 =A0 while (-1)
> >> =A0 =A0 =A0 =A0 {
> >> =A0 =A0 =A0 =A0 =A0 =A0 for(;
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex1 && *ptrIndex1 !=3D *strTarg=
et;
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ptrIndex1++);
> >> =A0 =A0 =A0 =A0 =A0 =A0 for(ptrIndex2 =3D strTarget, ptrIndex3 =3D ptr=
Index1;
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex3
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 &&
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex2
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 &&
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex3 =3D=3D *ptrIndex2;
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ptrIndex3++, ptrIndex2++);
> >> =A0 =A0 =A0 =A0 =A0 =A0 if (!*ptrIndex2) break;
> >> =A0 =A0 =A0 =A0 =A0 =A0 ptrIndex1 =3D ptrIndex3;
> >> =A0 =A0 =A0 =A0 =A0 =A0 if (!*ptrIndex3) break;
> >> =A0 =A0 =A0 =A0 }
>
> > These hunks are essentially performing the same part of the core loop;
> > find the next occurrence of the target string in the original string.
>
> > The second one was written by Edward Nilges ("spinoza1111"). =A0He offe=
rs
> > in its defense the assertion that it's the "best" algorithm. =A0(Neverm=
ind
> > that it's got a bug; the bug could be fixed easily.)
>
> > My thinking:
>
> > The first is better, not because it's less buggy (that could be fixed),=
but
> > because it's simpler to understand. =A0It may, or may not, be less effi=
cient.
> > However, efficiency will vary widely with input characteristics; for so=
me
> > cases, the arguable inefficiencies may be completely irrelevant, while =
in
> > others, they'd be significant.
>
> I don't think you can dismiss the bugs so easily. =A0I would argue that
> it is not a coincidence that the more complex code has more bugs. =A0I
> can't write code that looks likespinoza1111'scode and get it right.
> I *have* to write simpler code, broken into simple functions, or I have
> no chance of getting it to be correct.
>
> For example, the latest improvement introduced another bug[1] and I
> don't think that is simple carelessness. =A0Without a re-write I suspect
> almost any change is as likely to introduce a bug as fix one (I tried
> to see where the error was, but I gave up). =A0If I was paid to fix it,
> I'd simply start again and it would end a up as I have already posted,
> though to mirror the behaviour I'd now have to add some argument
> checking.
>
> <snip>
>
> [1] Apparently when the target string is not present in the source
> string: e.g. replace("a", "x", "b").

I have returned to this little project following my sabbatical to let
other people post their views.

Good call.

Replace "x" by "b" in "a"
Expect "a":
"ab"
Replacements expected: 0: replacements: 1
Assertion failed

I am fixing the problem, now, because unlike Seebach, I fix my bugs.
It's 1:09 AM 13 Feb.

Gung hey fat choi.
>
> --
> Ben.

```
 0
spinoza1111 (3246)
2/12/2010 5:10:36 PM
```On Feb 11, 9:05=A0am, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
> Seebs <usenet-nos...@seebs.net> writes:
> > This may have gotten buried given that it started in a Nilges thread,
> > but it's actually pretty interesting.
>
> > There was some discussion of algorithms to perform the task:
> > =A0 =A0Inputs: =A0target string, replacement string, original string
> > =A0 =A0Output: =A0a newly-allocated string containing the original
> > =A0 =A0 =A0string with each copy of the target string replaced with the
> > =A0 =A0 =A0replacement string.
>
> > Here's a hunk of mine:
>
> > =A0 =A0 =A0 =A0 for (count =3D 0, t =3D strstr(target, in); t && *t; t =
=3D strstr(t, in)) {
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ++count;
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 t +=3D inlen;
> > =A0 =A0 =A0 =A0 }
>
> > Here's a hunk of another one:
>
> >> =A0 =A0 ptrIndex1 =3D strMaster;
> >> =A0 =A0 while(*ptrIndex1)
> >> =A0 =A0 {
> >> =A0 =A0 =A0 =A0 ptrIndex0 =3D ptrIndex1;
> >> =A0 =A0 =A0 =A0 while (-1)
> >> =A0 =A0 =A0 =A0 {
> >> =A0 =A0 =A0 =A0 =A0 =A0 for(;
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex1 && *ptrIndex1 !=3D *strTarg=
et;
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ptrIndex1++);
> >> =A0 =A0 =A0 =A0 =A0 =A0 for(ptrIndex2 =3D strTarget, ptrIndex3 =3D ptr=
Index1;
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex3
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 &&
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex2
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 &&
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex3 =3D=3D *ptrIndex2;
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ptrIndex3++, ptrIndex2++);
> >> =A0 =A0 =A0 =A0 =A0 =A0 if (!*ptrIndex2) break;
> >> =A0 =A0 =A0 =A0 =A0 =A0 ptrIndex1 =3D ptrIndex3;
> >> =A0 =A0 =A0 =A0 =A0 =A0 if (!*ptrIndex3) break;
> >> =A0 =A0 =A0 =A0 }
>
> > These hunks are essentially performing the same part of the core loop;
> > find the next occurrence of the target string in the original string.
>
> > The second one was written by Edward Nilges ("spinoza1111"). =A0He offe=
rs
> > in its defense the assertion that it's the "best" algorithm. =A0(Neverm=
ind
> > that it's got a bug; the bug could be fixed easily.)
>
> > My thinking:
>
> > The first is better, not because it's less buggy (that could be fixed),=
but
> > because it's simpler to understand. =A0It may, or may not, be less effi=
cient.
> > However, efficiency will vary widely with input characteristics; for so=
me
> > cases, the arguable inefficiencies may be completely irrelevant, while =
in
> > others, they'd be significant.
>
> I don't think you can dismiss the bugs so easily. =A0I would argue that
> it is not a coincidence that the more complex code has more bugs. =A0I
> can't write code that looks likespinoza1111'scode and get it right.
> I *have* to write simpler code, broken into simple functions, or I have
> no chance of getting it to be correct.
>
> For example, the latest improvement introduced another bug[1] and I
> don't think that is simple carelessness. =A0Without a re-write I suspect
> almost any change is as likely to introduce a bug as fix one (I tried
> to see where the error was, but I gave up). =A0If I was paid to fix it,
> I'd simply start again and it would end a up as I have already posted,
> though to mirror the behaviour I'd now have to add some argument
> checking.
>
> <snip>
>
> [1] Apparently when the target string is not present in the source
> string: e.g. replace("a", "x", "b").
>
> --
> Ben.

It took me about an hour to fix this because of some blind alleys. See
the Change Record for 13 Feb for the explanation of the bug, a failure
to anticipate that there could be a situation when the main scan
pointer (ptrIndex1) and the main target pointer (ptrIndex2) both point
to Nul but the strings do not match.

In addition, I discovered that there are cases when I initialize the
secondary scan pointer ptrIndex3 to one past the Nul that terminates
the master string, and this has also been fixed.

The purpose of my style and approach is to reduce the bug rate
exponentially going forward. I don't post code while saying "it has a
bug, but it's easy to fix". This was Peter Seebach's initial mistake:
he posted a crappy solution to replacing %s that used a character scan
that fails when a percent occurs in the input, admitting the bug
without bothering to fix it.

This is why I have retained so many tests, and why I wrote a TESTER
macro, and why I formatted the code more carefully than most little
code monkeys care to format their code.

This is the arrogant programmer who expects others to clean up his
messes for him (and lies about people to get his way, I might add).

Having said all this, I am not completely happy with my solution. This
is because I have no assurance that there might be other cases where
it fails, and this in turn is because it's just code, not theory. In
terms of CS theory, it's doing two things at once: finding strings,
and replacing them. As I have said, it arbitrarily goes left to right
and doesn't handle overlapping hits in the way some applications might
require replace("banana", "ana", "xxx") to yield bxxxxx.

[In rereading Cormen's Algorithms the other night on string matching,
which treats the problem separate from match/replace for solid
theoretical reasons, I noticed that one of his students brought this
to his attention.]

Programmers who backstab and lie, who mock others who fix their bugs
for having the bugs, while grinning about their own, and who present
code with bugs that they won't fix, create buggy solutions out of
dishonesty. They helped to cause the credit crisis, because in many
cases, securitized mortgages and their derivative contracts were never
examined for loops such that one derivative referred to itself through
a chain. It increasingly appears that bugs in software lie at the
bottom of the Toyota recall.

Dijkstra is right. Programming IS too hard for Republicans and other
liars (Peter Seebach is on record as a Bush supporter, at least in
2000).

// ***************************************************************
// *                                                             *
// * replace() demo                                              *
// *                                                             *
// * Demonstrates how to replace non-NUL-defined strings in C    *
// * using a simple function, and bypassing string.h.            *
// *                                                             *
// * C H A N G E   R E C O R D --------------------------------- *
// *   DATE     PROGRAMMER     DESCRIPTION OF CHANGE             *
// * --------   ----------     --------------------------------- *
// * 02 07 10   Nilges         Version 1.0                       *
// *                                                             *
// * 02 07 10   Nilges         Bug: partial matches not handled  *
// *                           correctly: need to iterate search *
// *                           for match.                        *
// *                                                             *
// * 02 07 10   Nilges         1.  Santosh suggested tests       *
// *                           2.  Heathfield put the boot in re *
// *                               including malloc              *
// *                                                             *
// * 02 07 10   Nilges         1.  Remove string.h use and code  *
// *                               strlen by hand                *
// *                               inline.                       *
// *                           3.  free() storage                *
// *                           4.  Use macro for testing         *
// *                           5.  Bug: calculation of           *
// *                               lngNewLength used incorrect   *
// *                               index (intIndex3 instead of 2)*
// *                               which caused a memory leak.   *
// *                                                             *
// * 02 07 10   Nilges         1.  Bug: Ike Naar test failed.    *
// *                               At end of scan loop, main     *
// *                               string pointer was not        *
// *                               correctly updated from index3 *
// *                                                             *
// * 02 07 10   Nilges         Added new Santosh test            *
// *                                                             *
// * 02 07 10   Nilges         Added new Ike Naar test           *
// *                                                             *
// * 02 08 10   Nilges         1.  Added some new comments       *
// *                           2.  Make "check for a complete    *
// *                               match "structured" by means   *
// *                               of a tested assignment        *
// *                           3.  Get rid of "replace at end"   *
// *                               evilness: the only time this  *
// *                               flag is meaningful is in the  *
// *                               LAST segment.                 *
// *                           4.  Return replace count          *
// *                           5.  TESTER macro assertion added  *
// *                                                             *
// * 02 10 10   Nilges         1.  Bug fix: in a partial match,  *
// *                               the main scan index is set to *
// *                               one past the end, which misses*
// *                               full matches that start       *
// *                               between the first character of*
// *                               the partial match and its end.*
// *                                                             *
// *                               No longer updating the main   *
// *                               scan index (ptrIndex1) to the *
// *                               point of partial match        *
// *                               failure: setting it one past  *
// *                               the first character of the    *
// *                               partial match.                *
// *                                                             *
// *                           2.  Line up expected & actual     *
// *                               results per excellent         *
// *                               suggestion (who made this?)   *
// *                                                             *
// *                           3.  After a partial match, update *
// *                               the main handle search index  *
// *                               (ptrIndex1) to the first      *
// *                               occurrence of the handle      *
// *                               character after the start of  *
// *                               the partial match, or to the  *
// *                               index of the unmatched char.  *
// *                                                             *
// * 021310     Nilges         Bug: failed to handle a one-char  *
// *                           replace (of a by x in b) since    *
// *                           we set ptrIndex2 to point to NUL  *
// *                           which made it appear that there   *
// *                           was a match. When the main index  *
// *                           to the master string (ptrIndex1)  *
// *                           goes off the end of a cliff, we   *
// *                           needed to break out of the search *
// *                           loop.                             *
// *                                                             *
// *                           This also entailed setting the    *
// *                           target index ptrIndex2 to 0 at the*
// *                           beginning of each search so that  *
// *                           it is not erroneously used to     *
// *                           indicate that there's an insert   *
// *                           needed at the end.                *
// *                                                             *
// *                           to verify that the code works     *
// *                           when the string and target end    *
// *                           at the same time.                 *
// * ----------------------------------------------------------- *
// *                                                             *
// * "In the near future we shall have to live with the          *
// *  superstition that programming is 'so easy that even a      *
// *  Republican can do it!'"                                    *
// *                                                             *
// *                   - E. W. Dijkstra                          *
// *                                                             *
// *                                                             *
// ***************************************************************
#include <stdio.h>
#include <stdlib.h>
// ***** Segmentation *****
struct TYPsegmentstruct
{ char * strSegment;
long lngSegmentLength;
struct TYPsegmentstruct * ptrNext; };
// ---------------------------------------------------------------
// Calculate string length
//
//
long strLength(char *strInstring)
{
char *ptrInstring;
for (ptrInstring =3D strInstring; *ptrInstring; ptrInstring++);
return ptrInstring - strInstring;
}

// ---------------------------------------------------------------
// Replace target by replacement string in master string
//
//
// Caution: the string returned by this function should be freed.
//
//
char * replace(char * strMaster,
char * strTarget,
char * strReplacement,
long * ptrReplacements)
{
char * ptrIndex0;
char * ptrIndex1;
char * ptrIndex2;
char * ptrIndex3;
char * ptrIndex4;
char * strNew;
char * strNewStart;
long lngNewLength;
long lngCount;
long lngReplacementLength;
struct TYPsegmentstruct * ptrSegmentStructStarts;
struct TYPsegmentstruct * ptrSegmentStruct;
struct TYPsegmentstruct * ptrSegmentStructPrev;
lngReplacementLength =3D strLength(strReplacement);
if (!*strTarget)
{
printf("Error in calling replace(): target can't be null");
abort();
}
ptrIndex1 =3D strMaster;
ptrSegmentStructPrev =3D 0;
lngNewLength =3D 0;
*ptrReplacements =3D 0;
while(*ptrIndex1)
{
ptrIndex0 =3D ptrIndex1;
ptrIndex2 =3D 0;
while (-1)
{
// --- Check for (one character) handle
for(;
*ptrIndex1 && *ptrIndex1 !=3D *strTarget;
ptrIndex1++);
if (!*ptrIndex1) break;
// --- Check for complete match while remembering the
// --- last position of the handle
ptrIndex4 =3D 0;
for(ptrIndex2 =3D strTarget + 1,
ptrIndex3 =3D ptrIndex1 + 1;
*ptrIndex3
&&
*ptrIndex2
&&
*ptrIndex3 =3D=3D *ptrIndex2;
ptrIndex3++, ptrIndex2++)
{
if (*ptrIndex3 =3D=3D *strTarget
&&
ptrIndex4 =3D=3D 0) ptrIndex4 =3D ptrIndex3;
}
// End test: check complete match, update main ptr past
// partial match while checking for end of loop
if ((!*ptrIndex2 ? ((*ptrReplacements)++, -1) : 0)
||
(!*ptrIndex3 ? (ptrIndex1 =3D ptrIndex3, -1) : 0))
break;
// Update the main search pointer
ptrIndex1 =3D (ptrIndex4 =3D=3D 0 ? ptrIndex3 : ptrIndex4);
}
// --- Create new segment
if (!(ptrSegmentStruct =3D
malloc(sizeof(struct TYPsegmentstruct))))
abort();
ptrSegmentStruct->strSegment =3D ptrIndex0;
ptrSegmentStruct->lngSegmentLength =3D
ptrIndex1 - ptrIndex0;
ptrSegmentStruct->ptrNext =3D 0;
if (ptrSegmentStructPrev !=3D 0)
ptrSegmentStructPrev->ptrNext =3D ptrSegmentStruct;
else
ptrSegmentStructStarts =3D ptrSegmentStruct;
ptrSegmentStructPrev =3D ptrSegmentStruct;
// --- Update mallocation length
lngNewLength +=3D ptrSegmentStruct->lngSegmentLength +
(ptrIndex2 && !*ptrIndex2
?
lngReplacementLength
:
0);
// --- Get past end of target string & iterate
if (*ptrIndex1) ptrIndex1 =3D ptrIndex3;
}
// --- Allocate just enough storage for the new string
if (!(strNewStart =3D malloc(lngNewLength + 1))) abort();
// --- Build the new string whilst freeing the list
strNew =3D strNewStart;
ptrSegmentStruct =3D ptrSegmentStructStarts;
while (ptrSegmentStruct)
{
for (ptrIndex1 =3D ptrSegmentStruct->strSegment,
lngCount =3D 0;
lngCount < ptrSegmentStruct->lngSegmentLength;
ptrIndex1++, lngCount++, strNew++)
*strNew =3D *ptrIndex1;
if (ptrSegmentStruct->ptrNext
||
ptrIndex2 !=3D 0 && !*ptrIndex2)
for (ptrIndex1 =3D strReplacement;
*ptrIndex1;
ptrIndex1++, ++strNew)
*strNew =3D *ptrIndex1;
ptrSegmentStructPrev =3D ptrSegmentStruct;
ptrSegmentStruct =3D ptrSegmentStruct->ptrNext;
free(ptrSegmentStructPrev);
}
*strNew =3D '\0';
return strNewStart;
}

// ---------------------------------------------------------------
// Statement-format test macro
//
//
#define TESTER(resultPtr, master, target, replacement, expected,
expectedReplacements, replacements) \
{ \
printf("Replace \"%s\" by \"%s\" in \"%s\"\n", \
(target), (replacement), (master)); \
printf("Expect \"%s\":\n       \"%s\"\n", \
(expected), \
resultPtr =3D replace((master), \
(target), \
(replacement), \
&(replacements))); \
printf("Replacements expected: %d: replacements: %d\n", \
(expectedReplacements), \
(replacements)); \
if (!(strLength(resultPtr) \
=3D=3D \
strLength(master) \
+ \
(strLength(replacement)-strLength(target)) \
* \
replacements)) \
printf("Assertion failed\n"); \
printf("\n\n"); \
free(resultPtr); \
}

// ---------------------------------------------------------------
// Main procedure
//
//
int main()
{
char *ptrResult;
long lngReplacements;
printf("\nReplace\n\n\n");
TESTER(ptrResult,
"1111123bbb1111123bbb11123bb11111231111112111111123",
"111123",
"ono",
"1onobbb1onobbb11123bb1ono1111112111ono",
4,
lngReplacements)
TESTER(ptrResult,
"bbb1111123bbbbb",
"111123",
"ono",
"bbb1onobbbbb",
1,
lngReplacements)
TESTER(ptrResult,
"a stupid error",
"stupid error",
"miracle",
"a miracle",
1,
lngReplacements)
TESTER(ptrResult,
"a stupid error",
"stupid",
"miracle",
"a miracle error",
1,
lngReplacements)
TESTER(ptrResult,
"the stupid error",
"the stupid error",
"a miracle",
"a miracle",
1,
lngReplacements)
TESTER(ptrResult,
"the miracle",
"the",
"a",
"a miracle",
1,
lngReplacements)
TESTER(ptrResult,
"a miraclsnirpKamunkle",
"snirpKamunkle",
"e",
"a miracle",
1,
lngReplacements)
TESTER(ptrResult,
"a miraclesnirpKamunkle",
"a miracle",
"",
"snirpKamunkle",
1,
lngReplacements)
TESTER(ptrResult,
" a miraclesnirpKamunkle",
"a miracle",
"",
" snirpKamunkle",
1,
lngReplacements)
TESTER(ptrResult,
" a miraclesnirpKamunklea miraclea miracle",
"a miracle",
"",
" snirpKamunkle",
3,
lngReplacements)
TESTER(ptrResult,
"a miracle a miraclesnirpKamunkle a Miraclea miraclea
miracle",
"a miracle",
"",
" snirpKamunkle a Miracle",
4,
lngReplacements)
TESTER(ptrResult,
"a stupid errord",
"stupid error",
"miracle",
"a miracled",
1,
lngReplacements)
TESTER(ptrResult,
"a stupid errod",
"stupid error",
"miracle",
"a stupid errod",
0,
lngReplacements)
TESTER(ptrResult,
"a sstupid error",
"stupid error",
"miracle",
"a smiracle",
1,
lngReplacements)
TESTER(ptrResult,
"a stupid errorstupid error",
"stupid error",
"miracle",
"a miraclemiracle",
2,
lngReplacements)
TESTER(ptrResult,
"a stupid error stupiderror",
"stupid error",
"miracle",
"a miracle stupiderror",
1,
lngReplacements)
TESTER(ptrResult,
"bbbbbbbbbb",
"b",
"a",
"aaaaaaaaaa",
10,
lngReplacements)
TESTER(ptrResult,
"In the halls of R'yleh great %s lies dreaming",
"%s",
"Cthulu",
"In the halls of R'yleh great Cthulu lies dreaming",
1,
lngReplacements)
TESTER(ptrResult,
"%s%s%s%s%s%s",
"%s",
"Cthulu",
"CthuluCthuluCthuluCthuluCthuluCthulu",
6,
lngReplacements)
TESTER(ptrResult,
"banana",
"ana",
"oat",
"boatna",
1,
lngReplacements)
TESTER(ptrResult,
" a stupid errorstupid errorHeystupid errors",
"stupid error",
"+",
" a ++Hey+s",
3,
lngReplacements)
TESTER(ptrResult,
"foo barfoo barf",
"foo bar",
"bas",
"basbasf",
2,
lngReplacements)
TESTER(ptrResult,
"abab",
"ba",
"ba",
"abab",
1,
lngReplacements)
TESTER(ptrResult,
"abab",
"bab",
"boop",
"aboop",
1,
lngReplacements)
TESTER(ptrResult,
"banana",
"ana",
"ono",
"bonona",
1,
lngReplacements)
TESTER(ptrResult,
"a",
"x",
"b",
"a",
0,
lngReplacements)
TESTER(ptrResult,
"x",
"x",
"b",
"b",
1,
lngReplacements)
TESTER(ptrResult,
"egregious",
"egregious",
"egregious",
"egregious",
1,
lngReplacements)
TESTER(ptrResult,
"egregious",
"egregious",
"x",
"x",
1,
lngReplacements)
printf("\n\nTesting complete: check output carefully: \"Assertion
failed\" should not occur!\n\n");
return 0;
}

Replace

Replace "111123" by "ono" in
"1111123bbb1111123bbb11123bb11111231111112111111123"
Expect "1onobbb1onobbb11123bb1ono1111112111ono":
"1onobbb1onobbb11123bb1ono1111112111ono"
Replacements expected: 4: replacements: 4

Replace "111123" by "ono" in "bbb1111123bbbbb"
Expect "bbb1onobbbbb":
"bbb1onobbbbb"
Replacements expected: 1: replacements: 1

Replace "stupid error" by "miracle" in "a stupid error"
Expect "a miracle":
"a miracle"
Replacements expected: 1: replacements: 1

Replace "stupid" by "miracle" in "a stupid error"
Expect "a miracle error":
"a miracle error"
Replacements expected: 1: replacements: 1

Replace "the stupid error" by "a miracle" in "the stupid error"
Expect "a miracle":
"a miracle"
Replacements expected: 1: replacements: 1

Replace "the" by "a" in "the miracle"
Expect "a miracle":
"a miracle"
Replacements expected: 1: replacements: 1

Replace "snirpKamunkle" by "e" in "a miraclsnirpKamunkle"
Expect "a miracle":
"a miracle"
Replacements expected: 1: replacements: 1

Replace "a miracle" by "" in "a miraclesnirpKamunkle"
Expect "snirpKamunkle":
"snirpKamunkle"
Replacements expected: 1: replacements: 1

Replace "a miracle" by "" in " a miraclesnirpKamunkle"
Expect " snirpKamunkle":
" snirpKamunkle"
Replacements expected: 1: replacements: 1

Replace "a miracle" by "" in " a miraclesnirpKamunklea miraclea
miracle"
Expect " snirpKamunkle":
" snirpKamunkle"
Replacements expected: 3: replacements: 3

Replace "a miracle" by "" in "a miracle a miraclesnirpKamunkle a
Miraclea miraclea miracle"
Expect " snirpKamunkle a Miracle":
" snirpKamunkle a Miracle"
Replacements expected: 4: replacements: 4

Replace "stupid error" by "miracle" in "a stupid errord"
Expect "a miracled":
"a miracled"
Replacements expected: 1: replacements: 1

Replace "stupid error" by "miracle" in "a stupid errod"
Expect "a stupid errod":
"a stupid errod"
Replacements expected: 0: replacements: 0

Replace "stupid error" by "miracle" in "a sstupid error"
Expect "a smiracle":
"a smiracle"
Replacements expected: 1: replacements: 1

Replace "stupid error" by "miracle" in "a stupid errorstupid error"
Expect "a miraclemiracle":
"a miraclemiracle"
Replacements expected: 2: replacements: 2

Replace "stupid error" by "miracle" in "a stupid error stupiderror"
Expect "a miracle stupiderror":
"a miracle stupiderror"
Replacements expected: 1: replacements: 1

Replace "b" by "a" in "bbbbbbbbbb"
Expect "aaaaaaaaaa":
"aaaaaaaaaa"
Replacements expected: 10: replacements: 10

Replace "%s" by "Cthulu" in "In the halls of R'yleh great %s lies
dreaming"
Expect "In the halls of R'yleh great Cthulu lies dreaming":
"In the halls of R'yleh great Cthulu lies dreaming"
Replacements expected: 1: replacements: 1

Replace "%s" by "Cthulu" in "%s%s%s%s%s%s"
Expect "CthuluCthuluCthuluCthuluCthuluCthulu":
"CthuluCthuluCthuluCthuluCthuluCthulu"
Replacements expected: 6: replacements: 6

Replace "ana" by "oat" in "banana"
Expect "boatna":
"boatna"
Replacements expected: 1: replacements: 1

Replace "stupid error" by "+" in " a stupid errorstupid errorHeystupid
errors"
Expect " a ++Hey+s":
" a ++Hey+s"
Replacements expected: 3: replacements: 3

Replace "foo bar" by "bas" in "foo barfoo barf"
Expect "basbasf":
"basbasf"
Replacements expected: 2: replacements: 2

Replace "ba" by "ba" in "abab"
Expect "abab":
"abab"
Replacements expected: 1: replacements: 1

Replace "bab" by "boop" in "abab"
Expect "aboop":
"aboop"
Replacements expected: 1: replacements: 1

Replace "ana" by "ono" in "banana"
Expect "bonona":
"bonona"
Replacements expected: 1: replacements: 1

Replace "x" by "b" in "a"
Expect "a":
"a"
Replacements expected: 0: replacements: 0

Replace "x" by "b" in "x"
Expect "b":
"b"
Replacements expected: 1: replacements: 1

Replace "egregious" by "egregious" in "egregious"
Expect "egregious":
"egregious"
Replacements expected: 1: replacements: 1

Replace "egregious" by "x" in "egregious"
Expect "x":
"x"
Replacements expected: 1: replacements: 1

Testing complete: check output carefully: "Assertion failed" should
not occur!
```
 0
spinoza1111 (3246)
2/12/2010 6:46:47 PM
```On Feb 11, 9:46=A0am, Seebs <usenet-nos...@seebs.net> wrote:
> On 2010-02-11, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
>
> > I don't think you can dismiss the bugs so easily. =A0I would argue that
> > it is not a coincidence that the more complex code has more bugs. =A0I
> > can't write code that looks likespinoza1111'scode and get it right.
> > I *have* to write simpler code, broken into simple functions, or I have
> > no chance of getting it to be correct.
>
> You may be right on this. =A0Certainly, this kind of thing is one of the
> major reasons that I sometimes rewrite things a few times until I am
> sure I can understand the logic just by looking at it. =A0If I have to
> think it through, usually that means something is wrong, or the problem
> is extremely hard.
>
> > For example, the latest improvement introduced another bug[1] and I
> > don't think that is simple carelessness. =A0Without a re-write I suspec=
t
> > almost any change is as likely to introduce a bug as fix one (I tried
> > to see where the error was, but I gave up). =A0If I was paid to fix it,
> > I'd simply start again and it would end a up as I have already posted,
> > though to mirror the behaviour I'd now have to add some argument
> > checking.
>
> I think it would be interesting to start from his code and see whether it
> can be fixed by cleanups and refactoring. =A0I bet it could, although it'=
d
> certainly take longer than just writing one from scratch.

Well, unlike your original bug of scanning for % in two places as
ersatz for finding the string %s, it would be a simple matter for you
to use a modern editor to get rid of my Hungarian. And you cannot seem
to solve the problem from scratch without creating bugs that you won't
fix.
>
> But, e.g., starting by using names a little better than "ptrIndex1" and
> the like would make it a ton simpler.
>
> -s
> --
> Copyright 2010, all wrongs reversed. =A0Peter Seebach / usenet-nos...@see=
bs.nethttp://www.seebs.net/log/<-- lawsuits, religion, and funny picturesht=
tp://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!

```
 0
spinoza1111 (3246)
2/12/2010 6:48:38 PM
```On Feb 11, 5:01=A0pm, Nick Keighley <nick_keighley_nos...@hotmail.com>
wrote:
> On 11 Feb, 01:05, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
>
>
>
>
>
> > Seebs <usenet-nos...@seebs.net> writes:
> > > This may have gotten buried given that it started in a Nilges thread,
> > > but it's actually pretty interesting.
>
> > > There was some discussion of algorithms to perform the task:
> > > =A0 =A0Inputs: =A0target string, replacement string, original string
> > > =A0 =A0Output: =A0a newly-allocated string containing the original
> > > =A0 =A0 =A0string with each copy of the target string replaced with t=
he
> > > =A0 =A0 =A0replacement string.
>
> > > Here's a hunk of mine:
>
> > > =A0 =A0 =A0 =A0 for (count =3D 0, t =3D strstr(target, in); t && *t; =
t =3D strstr(t, in)) {
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ++count;
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 t +=3D inlen;
> > > =A0 =A0 =A0 =A0 }
>
> > > Here's a hunk of another one:
>
> > >> =A0 =A0 ptrIndex1 =3D strMaster;
> > >> =A0 =A0 while(*ptrIndex1)
> > >> =A0 =A0 {
> > >> =A0 =A0 =A0 =A0 ptrIndex0 =3D ptrIndex1;
> > >> =A0 =A0 =A0 =A0 while (-1)
> > >> =A0 =A0 =A0 =A0 {
> > >> =A0 =A0 =A0 =A0 =A0 =A0 for(;
> > >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex1 && *ptrIndex1 !=3D *strTa=
rget;
> > >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ptrIndex1++);
> > >> =A0 =A0 =A0 =A0 =A0 =A0 for(ptrIndex2 =3D strTarget, ptrIndex3 =3D p=
trIndex1;
> > >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex3
> > >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 &&
> > >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex2
> > >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 &&
> > >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex3 =3D=3D *ptrIndex2;
> > >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ptrIndex3++, ptrIndex2++);
> > >> =A0 =A0 =A0 =A0 =A0 =A0 if (!*ptrIndex2) break;
> > >> =A0 =A0 =A0 =A0 =A0 =A0 ptrIndex1 =3D ptrIndex3;
> > >> =A0 =A0 =A0 =A0 =A0 =A0 if (!*ptrIndex3) break;
> > >> =A0 =A0 =A0 =A0 }
>
> > > These hunks are essentially performing the same part of the core loop=
;
> > > find the next occurrence of the target string in the original string.
>
> > > The second one was written by Edward Nilges ("spinoza1111"). =A0He of=
fers
> > > in its defense the assertion that it's the "best" algorithm. =A0(Neve=
rmind
> > > that it's got a bug; the bug could be fixed easily.)
>
> > > My thinking:
>
> > > The first is better, not because it's less buggy (that could be fixed=
), but
> > > because it's simpler to understand. =A0It may, or may not, be less ef=
ficient.
> > > However, efficiency will vary widely with input characteristics; for =
some
> > > cases, the arguable inefficiencies may be completely irrelevant, whil=
e in
> > > others, they'd be significant.
>
> > I don't think you can dismiss the bugs so easily. =A0I would argue that
> > it is not a coincidence that the more complex code has more bugs. =A0I
> > can't write code that looks likespinoza1111'scode and get it right.
> > I *have* to write simpler code, broken into simple functions, or I have
> > no chance of getting it to be correct.
>
> "I now suggest that we confine ourselves to the design and
> implementation of intellectually manageable programs." Dijkstra

Amen, brother.

Dijkstra would say that we needed to disambiguate the two goals, and
that the unexpected complexity of "find and replace" results from the
fact that there are two things going on.

Perhaps we really need a string finder and a replacer which would
encapsulate left to right, right to left, and what to do on overlap.

However, the traditional way to do this can be slow, since it involves
creating a "table" of occurrences.

But two independent processes, a source and a sink, would handle the
problems nicely.
>
>
>
> > For example, the latest improvement introduced another bug[1] and I
> > don't think that is simple carelessness. =A0Without a re-write I suspec=
t
> > almost any change is as likely to introduce a bug as fix one (I tried
> > to see where the error was, but I gave up). =A0If I was paid to fix it,
> > I'd simply start again and it would end a up as I have already posted,
> > though to mirror the behaviour I'd now have to add some argument
> > checking.
>
> > <snip>
>
> > [1] Apparently when the target string is not present in the source
> > string: e.g. replace("a", "x", "b").

```
 0
spinoza1111 (3246)
2/12/2010 6:53:48 PM
```On Feb 11, 11:22=A0pm, John Bode <jfbode1...@gmail.com> wrote:
> On Feb 11, 2:09=A0am, "io_x" <a...@b.c.invalid> wrote:
>
> > "Dann Corbit" <dcor...@connx.com> ha scritto nel messaggionews:MPG.25dc=
bceb389a23e59896c8@news.eternal-september.org...
>
> [snip]
>
>
>
> > > For a standard library, the *most* important thing is correctness. =
=A0IOW,
>
> > for a standard library function
> > the *most* important thing is the easy to use
> > and the error handling well think
>
> It doesn't matter how easy to it is to use if it gives you the wrong
> It doesn't matter how well it handles errors if it gives you the wrong
> It doesn't matter how fast it is if it gives you the wrong answer.
> It doesn't matter how much memory it uses if it gives you the wrong
>
> Correctness comes first. =A0Then we can argue about everything else.

True, which is why I've responded to each bug report. But note that in
many industrial programming environments, where programming is a pure
cost center and creativity isn't wanted, responding to bugs can be
renarrated as having a lot of bugs.

This is why Peter admits bugs...but doesn't fix them.
```
 0
spinoza1111 (3246)
2/12/2010 6:56:19 PM
```On Feb 11, 9:22=A0am, John Bode <jfbode1...@gmail.com> wrote:
> On Feb 11, 2:09=A0am, "io_x" <a...@b.c.invalid> wrote:
>
> > "Dann Corbit" <dcor...@connx.com> ha scritto nel messaggionews:MPG.25dc=
bceb389a23e59896c8@news.eternal-september.org...
>
> [snip]
>
>
>
> > > For a standard library, the *most* important thing is correctness. =
=A0IOW,
>
> > for a standard library function
> > the *most* important thing is the easy to use
> > and the error handling well think
>
> It doesn't matter how easy to it is to use if it gives you the wrong
> It doesn't matter how well it handles errors if it gives you the wrong
> It doesn't matter how fast it is if it gives you the wrong answer.
> It doesn't matter how much memory it uses if it gives you the wrong
>
> Correctness comes first. =A0Then we can argue about everything else.

Correctness is to do with the implementation.  As a function in the
standard library, it is important to get its interface 'right' (which
relates to ease of use and error handling).

```
 0
2/12/2010 6:57:45 PM
```On Feb 12, 5:53=A0pm, Michael Foukarakis <electricde...@gmail.com>
wrote:
> On Feb 11, 2:47=A0pm, rich...@cogsci.ed.ac.uk (Richard Tobin) wrote:
>
> > In article <slrnhn628c.o3u.usenet-nos...@guild.seebs.net>,
>
> > Seebs =A0<usenet-nos...@seebs.net> wrote:
> > >But you should always write the simpler one first, and wait until you'=
ve
> > >profiled the code and verified that there's a bottleneck, and you know=
where
> > >it is, before trying to optimize.
>
> > But wouldn't that be Extreme Programming?
>
=3Den)
>
> Is that a Bad Thing=99?

Towards the end of my own programming career (I left the field to
become a teacher), I had very good experience with Extreme Programming
in Pairs. Surprisingly, the embodied humanity of the two people
working together, along with a little professionalism, helps even
enemies work on code together. I could probably even work with
Seebach, after I got finished slapping him around. Just
```
 0
spinoza1111 (3246)
2/12/2010 6:59:40 PM
```On Feb 11, 9:05=A0am, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
> Seebs <usenet-nos...@seebs.net> writes:
> > This may have gotten buried given that it started in a Nilges thread,
> > but it's actually pretty interesting.
>
> > There was some discussion of algorithms to perform the task:
> > =A0 =A0Inputs: =A0target string, replacement string, original string
> > =A0 =A0Output: =A0a newly-allocated string containing the original
> > =A0 =A0 =A0string with each copy of the target string replaced with the
> > =A0 =A0 =A0replacement string.
>
> > Here's a hunk of mine:
>
> > =A0 =A0 =A0 =A0 for (count =3D 0, t =3D strstr(target, in); t && *t; t =
=3D strstr(t, in)) {
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ++count;
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 t +=3D inlen;
> > =A0 =A0 =A0 =A0 }
>
> > Here's a hunk of another one:
>
> >> =A0 =A0 ptrIndex1 =3D strMaster;
> >> =A0 =A0 while(*ptrIndex1)
> >> =A0 =A0 {
> >> =A0 =A0 =A0 =A0 ptrIndex0 =3D ptrIndex1;
> >> =A0 =A0 =A0 =A0 while (-1)
> >> =A0 =A0 =A0 =A0 {
> >> =A0 =A0 =A0 =A0 =A0 =A0 for(;
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex1 && *ptrIndex1 !=3D *strTarg=
et;
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ptrIndex1++);
> >> =A0 =A0 =A0 =A0 =A0 =A0 for(ptrIndex2 =3D strTarget, ptrIndex3 =3D ptr=
Index1;
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex3
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 &&
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex2
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 &&
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex3 =3D=3D *ptrIndex2;
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ptrIndex3++, ptrIndex2++);
> >> =A0 =A0 =A0 =A0 =A0 =A0 if (!*ptrIndex2) break;
> >> =A0 =A0 =A0 =A0 =A0 =A0 ptrIndex1 =3D ptrIndex3;
> >> =A0 =A0 =A0 =A0 =A0 =A0 if (!*ptrIndex3) break;
> >> =A0 =A0 =A0 =A0 }
>
> > These hunks are essentially performing the same part of the core loop;
> > find the next occurrence of the target string in the original string.
>
> > The second one was written by Edward Nilges ("spinoza1111"). =A0He offe=
rs
> > in its defense the assertion that it's the "best" algorithm. =A0(Neverm=
ind
> > that it's got a bug; the bug could be fixed easily.)
>
> > My thinking:
>
> > The first is better, not because it's less buggy (that could be fixed),=
but
> > because it's simpler to understand. =A0It may, or may not, be less effi=
cient.
> > However, efficiency will vary widely with input characteristics; for so=
me
> > cases, the arguable inefficiencies may be completely irrelevant, while =
in
> > others, they'd be significant.
>
> I don't think you can dismiss the bugs so easily. =A0I would argue that
> it is not a coincidence that the more complex code has more bugs. =A0I
> can't write code that looks likespinoza1111'scode and get it right.
> I *have* to write simpler code, broken into simple functions, or I have
> no chance of getting it to be correct.
>
> For example, the latest improvement introduced another bug[1] and I

For the record, the bug was always there. My changes using the
extensive regression tests tend in my experience not to introduce new
bugs.

> don't think that is simple carelessness. =A0Without a re-write I suspect
> almost any change is as likely to introduce a bug as fix one (I tried
> to see where the error was, but I gave up). =A0If I was paid to fix it,

Then you did not understand the code. I agree that because it fuses
two different functions (find target and replace target) for
efficiency and the hell of it, it is a hard piece of code (and note
that no other solution I've seen adheres to my self-imposed rule of
not using string.h, yet most or all of the other solutions have bugs
that are announced but not fixed).

I also agree that reading C is hard. But if anyone could have
understood the code, you could have.

> I'd simply start again and it would end a up as I have already posted,
> though to mirror the behaviour I'd now have to add some argument
> checking.

....and not use string.h. I recall that you did. Please correct me if I
am wrong.
>
> <snip>
>
> [1] Apparently when the target string is not present in the source
> string: e.g. replace("a", "x", "b").
>
> --
> Ben.

```
 0
spinoza1111 (3246)
2/12/2010 7:36:56 PM
```On 2/12/2010 1:57 PM, Anand Hariharan wrote:
> On Feb 11, 9:22 am, John Bode<jfbode1...@gmail.com>  wrote:
>> On Feb 11, 2:09 am, "io_x"<a...@b.c.invalid>  wrote:
>>>
>>> for a standard library function
>>> the *most* important thing is the easy to use
>>> and the error handling well think
>>
>> It doesn't matter how easy to it is to use if it gives you the wrong
>> It doesn't matter how well it handles errors if it gives you the wrong
>> It doesn't matter how fast it is if it gives you the wrong answer.
>> It doesn't matter how much memory it uses if it gives you the wrong
>>
>> Correctness comes first.  Then we can argue about everything else.
>
> Correctness is to do with the implementation.  As a function in the
> standard library, it is important to get its interface 'right' (which
> relates to ease of use and error handling).

The rightness or wrongness of the interface is not the
implementation's to decide: It must implement the interface(s)
the governing standard(s) describe.  An implementation is *not*
at liberty to say "The fact that the FILE* argument is first
for fprintf() and last for fputs() is ugly; let's change fputs()
so the FILE* comes first and thereby improve the interface."
An implementation is *not* allowed to have strcat() return a
pointer to the output's terminating '\0' instead of to its
start, even though the latter would be more helpful.  And so
on: the standard dictates the interface, and the implementors
get no say in the matter.  (Some of us remember the pre-ANSI days
when implementors exercised their imagination more liberally; I
for one do not ever wish to return to that state of affairs.)

... which is not to say that I'm in love with the library as
it exists; the "bazaar" generates lots of annoying quirks.  But
that's The Way Things Are, and we learn to cope.  Implementors,
too, learn to cope.  And not to invent, not in this domain.

--
Eric Sosman
esosman@ieee-dot-org.invalid
```
 0
esosman2 (3096)
2/12/2010 11:06:03 PM
```On Feb 13, 7:06=A0am, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
> On 2/12/2010 1:57 PM, Anand Hariharan wrote:
>
>
>
>
>
> > On Feb 11, 9:22 am, John Bode<jfbode1...@gmail.com> =A0wrote:
> >> On Feb 11, 2:09 am, "io_x"<a...@b.c.invalid> =A0wrote:
>
> >>> for a standard library function
> >>> the *most* important thing is the easy to use
> >>> and the error handling well think
>
> >> It doesn't matter how easy to it is to use if it gives you the wrong
> >> It doesn't matter how well it handles errors if it gives you the wrong
> >> It doesn't matter how fast it is if it gives you the wrong answer.
> >> It doesn't matter how much memory it uses if it gives you the wrong
>
> >> Correctness comes first. =A0Then we can argue about everything else.
>
> > Correctness is to do with the implementation. =A0As a function in the
> > standard library, it is important to get its interface 'right' (which
> > relates to ease of use and error handling).
>
> =A0 =A0 =A0The rightness or wrongness of the interface is not the
> implementation's to decide: It must implement the interface(s)
> the governing standard(s) describe. =A0An implementation is *not*
> at liberty to say "The fact that the FILE* argument is first
> for fprintf() and last for fputs() is ugly; let's change fputs()
> so the FILE* comes first and thereby improve the interface."
> An implementation is *not* allowed to have strcat() return a
> pointer to the output's terminating '\0' instead of to its
> start, even though the latter would be more helpful. =A0And so
> on: the standard dictates the interface, and the implementors
> get no say in the matter. =A0(Some of us remember the pre-ANSI days
> when implementors exercised their imagination more liberally; I
> for one do not ever wish to return to that state of affairs.)
>
> =A0 =A0 =A0... which is not to say that I'm in love with the library as
> it exists; the "bazaar" generates lots of annoying quirks. =A0But
> that's The Way Things Are, and we learn to cope. =A0Implementors,
> too, learn to cope. =A0And not to invent, not in this domain.

This is an example of subservience to things (and ideas) which I find
limiting.

It's like the nonsense that started at Bell Northern Research three
years after I started and the incompetents came in.

Everyone divided themselves by tribes not defined by passion and
ability (which had created the two man tribe of Whitfield Diffie and
Bob Gaskins that invented Powerpoint) but by loyalty either to DEC or
IBM (this was the early 1980s).

Or more precisely:

We had fed the heart on fantasies,
The heart's grown brutal from the fare;
More substance in our enmities
Than in our love;

(WB Yeats, The Stare's Nest by My Window).

That is, the defects in the apparatus "loved" meant that the "love"
was merely a dislike of the other tribe.

This has devolved to the headhunter logic: that if an applicant has a
PhD in computer science and has implemented an OS for his thesis in C+
+, but the job requires C, she's not "qualified"...because the
headhunter (with some sort of crap business degree) can't put her into
an authoritarian box.

I'm programming in C at a somewhat higher level than anyone else in
this discussion, with all due humility. Nobody else has posted a
solution to the actual problem (do replace without string.h and fix
the bugs, don't stare at them), as far as I've seen. This despite the
fact that technically and in a unique way, I'm a newbie, having not
used C since 1991.

Learning a programming language per se (which is usually combined with
learning programming) is pretty trivial. In 1991, it was RTFM (reading
Internet to get up to speed, or back up. You make silly errors, but a
real man is unafraid to make silly errors (as opposed to many here).

What's amazing being that one can dip in almost anywhere in a semi-
philosopher/sociologist who worked at a rather low level white collar
job, and got fired for trying to do it effectively:

I.Q. =96 The modes of conduct appropriate to the most progressive
technical state of development are not limited to the sectors, in
which they are actually promoted. Thus thinking submits to the social
supervision of its services not only where it is forced to do so by
its occupation, but comes to resembles such in its entire complexion.
Because thought has been well-nigh inverted into the solution of tasks
assigned to it, what is not assigned is also dealt with according to
the schema of the task. Thought, having lost its autonomy, no longer
trusts itself to comprehend something real for its own sake, in
freedom. This it leaves, with respectful illusion, to the highest-
paid, and makes itself measurable for this. It tends to behave, for
its own part, as if it had to unceasingly portray its usefulness. Even
where there is no nutshell to crack, thinking turns into training [in
English in original] for some sort of exercise or other.

What is "real"? It's not using "obeying the rules of the C standard"
as an excuse for not fixing bugs. And given that many of the "annoying
quirks" of the existing libraries are real bugs or primitive
limitations imposed by older technology, it seems to be that you DO
have to invent.
> --
> Eric Sosman
> esos...@ieee-dot-org.invalid
```
 0
spinoza1111 (3246)
2/13/2010 6:04:13 AM
```On Feb 13, 2:46=A0am, spinoza1111 <spinoza1...@yahoo.com> wrote:
....code...

I noticed that in the latest (13 Feb) version of the code, with the
fix to the one-character replace found by Ben B, there were some file
nits: two long lines split and blanks at end of continued macro lines.

Let's see if I can get rid of these problems.

Also, I misspoke. The failure to handle Ben's example was caused by an
earlier change.

Here is the latest code, without the console output.

// ***************************************************************
// *                                                             *
// * replace() demo                                              *
// *                                                             *
// * Demonstrates how to replace non-NUL-defined strings in C    *
// * using a simple function, and bypassing string.h.            *
// *                                                             *
// * C H A N G E   R E C O R D --------------------------------- *
// *   DATE     PROGRAMMER     DESCRIPTION OF CHANGE             *
// * --------   ----------     --------------------------------- *
// * 02 07 10   Nilges         Version 1.0                       *
// *                                                             *
// * 02 07 10   Nilges         Bug: partial matches not handled  *
// *                           correctly: need to iterate search *
// *                           for match.                        *
// *                                                             *
// * 02 07 10   Nilges         1.  Santosh suggested tests       *
// *                           2.  Heathfield put the boot in re *
// *                               including malloc              *
// *                                                             *
// * 02 07 10   Nilges         1.  Remove string.h use and code  *
// *                               strlen by hand                *
// *                               inline.                       *
// *                           3.  free() storage                *
// *                           4.  Use macro for testing         *
// *                           5.  Bug: calculation of           *
// *                               lngNewLength used incorrect   *
// *                               index (intIndex3 instead of 2)*
// *                               which caused a memory leak.   *
// *                                                             *
// * 02 07 10   Nilges         1.  Bug: Ike Naar test failed.    *
// *                               At end of scan loop, main     *
// *                               string pointer was not        *
// *                               correctly updated from index3 *
// *                                                             *
// * 02 07 10   Nilges         Added new Santosh test            *
// *                                                             *
// * 02 07 10   Nilges         Added new Ike Naar test           *
// *                                                             *
// * 02 08 10   Nilges         1.  Added some new comments       *
// *                           2.  Make "check for a complete    *
// *                               match "structured" by means   *
// *                               of a tested assignment        *
// *                           3.  Get rid of "replace at end"   *
// *                               evilness: the only time this  *
// *                               flag is meaningful is in the  *
// *                               LAST segment.                 *
// *                           4.  Return replace count          *
// *                           5.  TESTER macro assertion added  *
// *                                                             *
// * 02 10 10   Nilges         1.  Bug fix: in a partial match,  *
// *                               the main scan index is set to *
// *                               one past the end, which misses*
// *                               full matches that start       *
// *                               between the first character of*
// *                               the partial match and its end.*
// *                                                             *
// *                               No longer updating the main   *
// *                               scan index (ptrIndex1) to the *
// *                               point of partial match        *
// *                               failure: setting it one past  *
// *                               the first character of the    *
// *                               partial match.                *
// *                                                             *
// *                           2.  Line up expected & actual     *
// *                               results per excellent         *
// *                               suggestion (who made this?)   *
// *                                                             *
// *                           3.  After a partial match, update *
// *                               the main handle search index  *
// *                               (ptrIndex1) to the first      *
// *                               occurrence of the handle      *
// *                               character after the start of  *
// *                               the partial match, or to the  *
// *                               index of the unmatched char.  *
// *                                                             *
// * 021310     Nilges         Bug: failed to handle a one-char  *
// *                           replace (of a by x in b) since    *
// *                           we set ptrIndex2 to point to NUL  *
// *                           which made it appear that there   *
// *                           was a match. When the main index  *
// *                           to the master string (ptrIndex1)  *
// *                           goes off the end of a cliff, we   *
// *                           needed to break out of the search *
// *                           loop.                             *
// *                                                             *
// *                           This also entailed setting the    *
// *                           target index ptrIndex2 to 0 at the*
// *                           beginning of each search so that  *
// *                           it is not erroneously used to     *
// *                           indicate that there's an insert   *
// *                           needed at the end.                *
// *                                                             *
// *                           to verify that the code works     *
// *                           when the string and target end    *
// *                           at the same time.                 *
// * ----------------------------------------------------------- *
// *                                                             *
// * "In the near future we shall have to live with the          *
// *  superstition that programming is 'so easy that even a      *
// *  Republican can do it!'"                                    *
// *                                                             *
// *                   - E. W. Dijkstra                          *
// *                                                             *
// *                                                             *
// ***************************************************************
#include <stdio.h>
#include <stdlib.h>
// ***** Segmentation *****
struct TYPsegmentstruct
{ char * strSegment;
long lngSegmentLength;
struct TYPsegmentstruct * ptrNext; };
// ---------------------------------------------------------------
// Calculate string length
//
//
long strLength(char *strInstring)
{
char *ptrInstring;
for (ptrInstring =3D strInstring; *ptrInstring; ptrInstring++);
return ptrInstring - strInstring;
}

// ---------------------------------------------------------------
// Replace target by replacement string in master string
//
//
// Caution: the string returned by this function should be freed.
//
//
char * replace(char * strMaster,
char * strTarget,
char * strReplacement,
long * ptrReplacements)
{
char * ptrIndex0;
char * ptrIndex1;
char * ptrIndex2;
char * ptrIndex3;
char * ptrIndex4;
char * strNew;
char * strNewStart;
long lngNewLength;
long lngCount;
long lngReplacementLength;
struct TYPsegmentstruct * ptrSegmentStructStarts;
struct TYPsegmentstruct * ptrSegmentStruct;
struct TYPsegmentstruct * ptrSegmentStructPrev;
lngReplacementLength =3D strLength(strReplacement);
if (!*strTarget)
{
printf("Error in calling replace(): target can't be null");
abort();
}
ptrIndex1 =3D strMaster;
ptrSegmentStructPrev =3D 0;
lngNewLength =3D 0;
*ptrReplacements =3D 0;
while(*ptrIndex1)
{
ptrIndex0 =3D ptrIndex1;
ptrIndex2 =3D 0;
while (-1)
{
// --- Check for (one character) handle
for(;
*ptrIndex1 && *ptrIndex1 !=3D *strTarget;
ptrIndex1++);
if (!*ptrIndex1) break;
// --- Check for complete match while remembering the
// --- last position of the handle
ptrIndex4 =3D 0;
for(ptrIndex2 =3D strTarget + 1,
ptrIndex3 =3D ptrIndex1 + 1;
*ptrIndex3
&&
*ptrIndex2
&&
*ptrIndex3 =3D=3D *ptrIndex2;
ptrIndex3++, ptrIndex2++)
{
if (*ptrIndex3 =3D=3D *strTarget
&&
ptrIndex4 =3D=3D 0) ptrIndex4 =3D ptrIndex3;
}
// End test: check complete match, update main ptr past
// partial match while checking for end of loop
if ((!*ptrIndex2 ? ((*ptrReplacements)++, -1) : 0)
||
(!*ptrIndex3 ? (ptrIndex1 =3D ptrIndex3, -1) : 0))
break;
// Update the main search pointer
ptrIndex1 =3D (ptrIndex4 =3D=3D 0 ? ptrIndex3 : ptrIndex4);
}
// --- Create new segment
if (!(ptrSegmentStruct =3D
malloc(sizeof(struct TYPsegmentstruct))))
abort();
ptrSegmentStruct->strSegment =3D ptrIndex0;
ptrSegmentStruct->lngSegmentLength =3D
ptrIndex1 - ptrIndex0;
ptrSegmentStruct->ptrNext =3D 0;
if (ptrSegmentStructPrev !=3D 0)
ptrSegmentStructPrev->ptrNext =3D ptrSegmentStruct;
else
ptrSegmentStructStarts =3D ptrSegmentStruct;
ptrSegmentStructPrev =3D ptrSegmentStruct;
// --- Update mallocation length
lngNewLength +=3D ptrSegmentStruct->lngSegmentLength +
(ptrIndex2 && !*ptrIndex2
?
lngReplacementLength
:
0);
// --- Get past end of target string & iterate
if (*ptrIndex1) ptrIndex1 =3D ptrIndex3;
}
// --- Allocate just enough storage for the new string
if (!(strNewStart =3D malloc(lngNewLength + 1))) abort();
// --- Build the new string whilst freeing the list
strNew =3D strNewStart;
ptrSegmentStruct =3D ptrSegmentStructStarts;
while (ptrSegmentStruct)
{
for (ptrIndex1 =3D ptrSegmentStruct->strSegment,
lngCount =3D 0;
lngCount < ptrSegmentStruct->lngSegmentLength;
ptrIndex1++, lngCount++, strNew++)
*strNew =3D *ptrIndex1;
if (ptrSegmentStruct->ptrNext
||
ptrIndex2 !=3D 0 && !*ptrIndex2)
for (ptrIndex1 =3D strReplacement;
*ptrIndex1;
ptrIndex1++, ++strNew)
*strNew =3D *ptrIndex1;
ptrSegmentStructPrev =3D ptrSegmentStruct;
ptrSegmentStruct =3D ptrSegmentStruct->ptrNext;
free(ptrSegmentStructPrev);
}
*strNew =3D '\0';
return strNewStart;
}

// ---------------------------------------------------------------
// Statement-format test macro
//
//
#define TESTER(resultPtr, master, target, replacement, expected,
expectedReplacements, replacements) \
{ \
printf("Replace \"%s\" by \"%s\" in \"%s\"\n", \
(target), (replacement), (master)); \
printf("Expect \"%s\":\n       \"%s\"\n", \
(expected), \
resultPtr =3D replace((master), \
(target), \
(replacement), \
&(replacements))); \
printf("Replacements expected: %d: replacements: %d\n", \
(expectedReplacements), \
(replacements)); \
if (!(strLength(resultPtr) \
=3D=3D \
strLength(master) \
+ \
(strLength(replacement)-strLength(target)) \
* \
replacements)) \
printf("Assertion failed\n"); \
printf("\n\n"); \
free(resultPtr); \
}

// ---------------------------------------------------------------
// Main procedure
//
//
int main()
{
char *ptrResult;
long lngReplacements;
printf("\nReplace\n\n\n");
TESTER(ptrResult,
"1111123bbb1111123bbb11123bb11111231111112111111123",
"111123",
"ono",
"1onobbb1onobbb11123bb1ono1111112111ono",
4,
lngReplacements)
TESTER(ptrResult,
"bbb1111123bbbbb",
"111123",
"ono",
"bbb1onobbbbb",
1,
lngReplacements)
TESTER(ptrResult,
"a stupid error",
"stupid error",
"miracle",
"a miracle",
1,
lngReplacements)
TESTER(ptrResult,
"a stupid error",
"stupid",
"miracle",
"a miracle error",
1,
lngReplacements)
TESTER(ptrResult,
"the stupid error",
"the stupid error",
"a miracle",
"a miracle",
1,
lngReplacements)
TESTER(ptrResult,
"the miracle",
"the",
"a",
"a miracle",
1,
lngReplacements)
TESTER(ptrResult,
"a miraclsnirpKamunkle",
"snirpKamunkle",
"e",
"a miracle",
1,
lngReplacements)
TESTER(ptrResult,
"a miraclesnirpKamunkle",
"a miracle",
"",
"snirpKamunkle",
1,
lngReplacements)
TESTER(ptrResult,
" a miraclesnirpKamunkle",
"a miracle",
"",
" snirpKamunkle",
1,
lngReplacements)
TESTER(ptrResult,
" a miraclesnirpKamunklea miraclea miracle",
"a miracle",
"",
" snirpKamunkle",
3,
lngReplacements)
TESTER(ptrResult,
"a miracle a miraclesnirpKamunkle a Miraclea
miracleamiracle",
"a miracle",
"",
" snirpKamunkle a Miracle",
4,
lngReplacements)
TESTER(ptrResult,
"a stupid errord",
"stupid error",
"miracle",
"a miracled",
1,
lngReplacements)
TESTER(ptrResult,
"a stupid errod",
"stupid error",
"miracle",
"a stupid errod",
0,
lngReplacements)
TESTER(ptrResult,
"a sstupid error",
"stupid error",
"miracle",
"a smiracle",
1,
lngReplacements)
TESTER(ptrResult,
"a stupid errorstupid error",
"stupid error",
"miracle",
"a miraclemiracle",
2,
lngReplacements)
TESTER(ptrResult,
"a stupid error stupiderror",
"stupid error",
"miracle",
"a miracle stupiderror",
1,
lngReplacements)
TESTER(ptrResult,
"bbbbbbbbbb",
"b",
"a",
"aaaaaaaaaa",
10,
lngReplacements)
TESTER(ptrResult,
"In the halls of R'yleh great %s lies dreaming",
"%s",
"Cthulu",
"In the halls of R'yleh great Cthulu lies dreaming",
1,
lngReplacements)
TESTER(ptrResult,
"%s%s%s%s%s%s",
"%s",
"Cthulu",
"CthuluCthuluCthuluCthuluCthuluCthulu",
6,
lngReplacements)
TESTER(ptrResult,
"banana",
"ana",
"oat",
"boatna",
1,
lngReplacements)
TESTER(ptrResult,
" a stupid errorstupid errorHeystupid errors",
"stupid error",
"+",
" a ++Hey+s",
3,
lngReplacements)
TESTER(ptrResult,
"foo barfoo barf",
"foo bar",
"bas",
"basbasf",
2,
lngReplacements)
TESTER(ptrResult,
"abab",
"ba",
"ba",
"abab",
1,
lngReplacements)
TESTER(ptrResult,
"abab",
"bab",
"boop",
"aboop",
1,
lngReplacements)
TESTER(ptrResult,
"banana",
"ana",
"ono",
"bonona",
1,
lngReplacements)
TESTER(ptrResult,
"a",
"x",
"b",
"a",
0,
lngReplacements)
TESTER(ptrResult,
"x",
"x",
"b",
"b",
1,
lngReplacements)
TESTER(ptrResult,
"egregious",
"egregious",
"egregious",
"egregious",
1,
lngReplacements)
TESTER(ptrResult,
"egregious",
"egregious",
"x",
"x",
1,
lngReplacements)
printf("\n\nTesting complete: check output carefully: \"Assertion
failed\" should not occur!\n\n");
return 0;
}
```
 0
spinoza1111 (3246)
2/13/2010 9:25:27 AM
```On Feb 13, 5:25=A0pm, spinoza1111 <spinoza1...@yahoo.com> wrote:

....latest code...

probably must:

1.  Remove all spaces after the continuation markers in the TESTER
macro (at least on the Microsoft compiler: isn't this a bug that the
backslash may not be followed by a space, or was this horse puckey
blessed by the standard?)

2.  Rejoin all lines split past position 67 if this is what your
browser does:

2.2 The test of "a miracle a miraclesnirpKamunkle a Miraclea
miracleamiracle": note that in the latest post, I screwed up the
repair of this line which is why you should get ONE unexpected result
in your test of the latest code. Sensible and well-intentioned
developers will be able to figure this one out on their own, although
Heathfield will probably start foaming at the mouth
2.3 The last printf

At this point the code still does what appears to be unnecessary work
in the form of examining partial matches that occur starting to the
left of another partial match. This is because it notes only the one-
character "handle" of the left-partial match.

However, we know that

*  No match can contain a match inside of it because it is
impossible for a proper substring of a string to match the containing
string, where a "proper" substring of X, X', is one of length(X)-n
where n>0. In simple English, a string cannot contain itself as a
proper substring. I think.

*  Therefore, if we find the character handle of the target
inside a partial or complete occurrence of the target, this is an
overlapping string starting at the handle.

It seemed like a good idea, perhaps because I am evading the issue of
Boyer, Moore, Knuth, Pratt, Morris and Snoid, this afternoon to put in
a subsearch for the n-character overlapping target inside the match
loop. But this proved to complexify the code both conceptually and in
the sense that the target matcher had to contain extra instructions:
"do we have a potential overlap?" and "is it matching as well as the
main scan?"

Buys you nothing. You might as well check the left overlap in the next
cycle of the loop.

I believe I have possibly arrived at the most efficient solution
possible without auxiliary tables, because my solution appears to
examine pairs of characters the least amount of times needed. Wow. But
that's one of those beautiful theories forever being set upon by
ruffians in the form of facts.

In view of the face that NO OTHER POSTER (to my knowledge) has met the
requirements (code a string replace function without string.h usage) I
hereby declare victory, and award myself the Golden Spinoza Order of
Purity and Truth har har.

Seriously, I have demonstrated, I believe, that Republicans can't code
worth dick, but they can (if Peter Seebach is still a Republican) say
"there is a bug in my code but I'm fucked if I'll fix it", and they
sure can backstab and lie. That is: there is an entire programming
world-view, a Gestalt, that is complete malarkey and normalized
deviance. It consists of the inchoate saws and maxims that have
accumulated over time, that have sifted down from on-high from capable
early developers, but which have become little more than a cargo
cult.

My code is hard to read, it is said (on dit). In a sense, it is. I
find it hard to read at times myself.

An entire story exists in the cargo cult of the programmer who is in
some versions of the story "too clever by half" and in others only
thinks he is, and who writes an enormous program that nobody can
figure out. The social function of the story is to normalize
differences in ability, and to cover up the fact that many companies
try to solve ill-defined and very hard problems with computers, often
in order to exploit their workers or cheat customers. It omits the
existence of real code written by ordinary members of the white collar
proletariat which solved in an unsung fashion a hard problem...such as
the assembler for the 8K IBM 1401 that was written by a Univ of Chi
graduate student that put the IBM assembler to shame.

When looking for work in the 1990s, I answered an ad from Rockwell-
Wescom, a telecom manufacturer in Chicago. During my interview, the
manager said "some guy many years ago figured out how to use our call
data to reconstruct calls by simulating the PBX: he was pretty
strange." I said, "that was me". I'd become a legend of the dreamtime.
I didn't get a job because, the manager said, I was "too good to be
true". There had to be something wrong with a guy who'd solved a
problem nobody else could solve but was looking for work in his
forties.

Whereas at a shipping conference in 2003 I was greeted with
recognition by the staff of a shipbuilding firm for whom I'd created a
key program in the 1980s. This was because their culture was one of
openness and trust, not myth, and it's important that at the
conference, they said that they weren't bothering to bid for work in
Iraq. It was an ethical firm, of the sort that is in my experience
rare.

Code in some instance might look challenging because the problem is
actually a bit hard. Likewise it was hard for NASA engineers to solve
the problem of O-ring temperatures in cold temperatures in the
Challenger space shuttle, and later for them to solve the problem of
foam insulation dropping off Columbia at launch.

"They say it couldn't be done. So, I didn't do it."

In a post-Enlightenment culture of real science that has sifted down
to low-level technicians distinguished only by their conformity,
passive-aggression, frightened political conservatism (or passive-
aggressive "libertarianism") and/or religious Fundamentalism, the
former science (including Dijkstra's misinterpreted admonitions
concerning simplicity and "the humble programmer") become a cargo cult
of excuses for normalized deviance.

In a recent collection of writings on popular music by my fat pal
Theodore Adorno, he sets out the contrast starkly between classical
and popular music, and this is applicable to programming.

Popular music, he wrote, seems free and liberating, but in actuality
is almost always oversimplified in structure (and this is still true
of pop music years after he wrote it). The dissonances and syncopation
rely for their effect, he wrote, on the fact that for the listener
they are not actual artistic and standalone statements, but instead
sardonic POINTERS (references) back to classical music, light
classical music, and more traditional pop music.

The pop composer, even Irving Berlin or Copland, relies for his effect
on a backreference which says inside the music "listen, I flatted that
note, but you can if you like normalize my deviance by treating what I
said as unserious".

Consider the difference between Phillip Glass or Ygor Stravinsky on
the one hand, and Alban Berg on the other. The audience, according to
a 1980s Time magazine article about Glass, happily "sighed" when
Glass's cheap backreferences to the most innocuous classical music
with an easy-listening rock beat started to drone. Likewise, the
anxious bourgeois applauded Stravinsky (and Picasso) in the 1920s when
they reverted to classical models by means of snarky backreferences
with just enough dissonance to make the audience feel hip.

Whereas Beethoven meant to write the entire symphony in such a way
that ANY change would damage the whole (whereas my formatting and
naming conventions are not something I can willingly discard). (I
really felt for Tom Hulce's Amadeus in the eponymous movie when he was
told to discard notes by the Emperor).

That is, the division is between serious and unserious in programming
as well as music (PJ Plauger's phrase applies: programming on
purpose).

A Pop culture, a cargo cult and culture, creates people like Seebach,
who lie and backstab as standard procedure, allows them to claim that
the bad is good, by formulaic protocol-statements and shibboleths that
have the same function as dissonance in Pop music: saying "oh and by
the way I don't look for %s" is a gesture possible only in a culture
sodden with Pop crap created to make money.

This isn't to say that there couldn't be "serious" Pop music, such as
Johnson wasn't commercially successful. Instead, rich men like Jagger
and McCartney stole what he did. Like Copland and Berlin, they relied
for their best effects on a form of plagiarism that mocks its source.
```
 0
spinoza1111 (3246)
2/13/2010 10:30:53 AM
```On 13/02/2010 10:30, spinoza1111 wrote:

> My code is hard to read, it is said (on dit). In a sense, it is. I
> find it hard to read at times myself.

Then it's shitty code, pure and simple.

--
Tim

"That the freedom of speech and debates or proceedings in Parliament
ought not to be impeached or questioned in any court or place out of
Parliament"

Bill of Rights 1689
```
 0
timstreater (945)
2/13/2010 10:43:54 AM
```"spinoza1111" <spinoza1111@yahoo.com> ha scritto nel messaggio
// ---------------------------------------------------------------
// Statement-format test macro
//
//
#define TESTER(resultPtr, master, target, replacement, expected,
expectedReplacements, replacements) \
{ \
printf("Replace \"%s\" by \"%s\" in \"%s\"\n", \
(target), (replacement), (master)); \
printf("Expect \"%s\":\n       \"%s\"\n", \
(expected), \
resultPtr = replace((master), \
(target), \
(replacement), \
&(replacements))); \
printf("Replacements expected: %d: replacements: %d\n", \
(expectedReplacements), \
(replacements)); \
if (!(strLength(resultPtr) \
== \
strLength(master) \
+ \
(strLength(replacement)-strLength(target)) \
* \
replacements)) \
printf("Assertion failed\n"); \
printf("\n\n"); \
free(resultPtr); \
}

I can not be agree on your way of build test function
like a macro: that is indebuggable.
Macro for me are for build one language or for doing little
substitution like in "P" ---> "printf"

this is my propose: write only when find one error
--------------------------------
#define  P  printf
#define  R  return

// origin has to came from malloc memory
int  tester(char* origin, char*  whatSost, char*  sost, char*  expected)
{char     *p;
unsigned len;
int       i;

if(origin==0||whatSost==0||sost==0||expected==0)
R  0;
p=Replace(&len, origin, whatSost, sost);
if(p==0)      R  0;
if(Strcmp(expected, p)!=0 || len!=Strlen(p))
{P("I find one error:\n");
P("Origin=%s|WhatS=%s|Sost=%s\n", origin, whatSost, sost);
P("Expect \"%s\":\nResult \"%s\"\n", expected, p);
P("lenResult=%u  strlenResult=%u\n", len, Strlen(p));
Free(p);
R  0;
}
Free(p);
R  1;
}

// ---------------------------------------------------------------
// test for Replace() function
//
int test1(void)
{   unsigned     r;
P("\n\nTest1\n");
r=1;
r*=tester("a stupid error","stupid error","miracle","a miracle");
r*=tester("a stupid error","stupid","miracle","a miracle error");
r*=tester("the stupid error","the stupid error","a miracle",
"a miracle");
r*=tester("the miracle","the","a","a miracle");
r*=tester("a miraclsnirpKamunkle","snirpKamunkle","e",
"a miracle");
r*=tester("a miraclesnirpKamunkle","a miracle",
"","snirpKamunkle");
r*=tester(" a miraclesnirpKamunkle","a miracle",
""," snirpKamunkle");
r*=tester(" a miraclesnirpKamunklea miraclea miracle","a miracle",
""," snirpKamunkle");
r*=tester("a miracle a miraclesnirpKamunkle a Miraclea miraclea miracle",
"a miracle",""," snirpKamunkle a Miracle");
r*=tester("a stupid errord","stupid error","miracle","a miracled");
r*=tester("a stupid errod","stupid error","miracle","a stupid errod");
r*=tester("a sstupid error","stupid error","miracle","a smiracle");
r*=tester("a stupid errorstupid error","stupid error","miracle",
"a miraclemiracle");
r*=tester("a stupid error stupiderror","stupid error","miracle",
"a miracle stupiderror");
r*=tester("bbbbbbbbbb","b","a","aaaaaaaaaa");
r*=tester("In the halls of R'yleh great %s lies dreaming","%s",
"Cthulu","In the halls of R'yleh great Cthulu lies dreaming");
r*=tester("%s%s%s%s%s%s","%s","Cthulu",
"CthuluCthuluCthuluCthuluCthuluCthulu");
r*=tester("banana","ana","oat","boatna");
r*=tester(" a stupid errorstupid errorHeystupid errors","stupid error",
"+"," a ++Hey+s");
r*=tester("foo barfoo barf","foo bar","bas","basbasf");
r*=tester("abab","ba","ba","abab");
r*=tester("a", "a", "b", "b");

if(r==0) {P("Test 1: Some error occurs\a\n\n"); R  0;}
else      P("Test 1: Find  No error\n\n");
R  1;
}

```
 0
io_x
2/13/2010 11:05:12 AM
```spinoza1111 wrote:
<snip>

I see you've ditched malloc.h, so here are my next two observations:

> // Calculate string length
> //
> //
> long strLength(char *strInstring)
> {
>     char *ptrInstring;
>     for (ptrInstring = strInstring; *ptrInstring; ptrInstring++);
>     return ptrInstring - strInstring;
> }

long strLength(const char *s)
{
long len = 0;
while(*s++) ++len;
return len;
}

Other suggested improvements: (a) use an unsigned type, such as unsigned
long (strings might have 0 length, but they can never be negatively
long); and (b) drop the function completely, in favour of strlen.

<snip>

>     if (!*strTarget)
>     {
>         printf("Error in calling replace(): target can't be null");
>         abort();

If you intend this to be a general purpose solution, calling abort() is
not a good idea.

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
```
 0
rjh (10791)
2/13/2010 11:22:56 AM
```On Feb 13, 6:43=A0pm, Tim Streater <timstrea...@waitrose.com> wrote:
> On 13/02/2010 10:30,spinoza1111wrote:
>
> > My code is hard to read, it is said (on dit). In a sense, it is. I
> > find it hard to read at times myself.
>
> Then it's shitty code, pure and simple.

That is the common view. I regard it as self-indulgent. Who says you
>
> --
> Tim
>
> "That the freedom of speech and debates or proceedings in Parliament
> ought not to be impeached or questioned in any court or place out of
> Parliament"
>
> Bill of Rights 1689

```
 0
spinoza1111 (3246)
2/13/2010 11:53:01 AM
```Richard Heathfield <rjh@see.sig.invalid> writes:

> spinoza1111 wrote:
> <snip>
>
> I see you've ditched malloc.h, so here are my next two observations:
>
>> // Calculate string length
>> //
>> //
>> long strLength(char *strInstring)
>> {
>>     char *ptrInstring;
>>     for (ptrInstring = strInstring; *ptrInstring; ptrInstring++);
>>     return ptrInstring - strInstring;
>> }
>
>
> long strLength(const char *s)
> {
>    long len = 0;
>    while(*s++) ++len;
>    return len;
> }

An unnecessary increment on every loop. Potentially expensive for long
blocks. Nilges might be faster in many cases.
```
 0
rgrdev_ (1097)
2/13/2010 12:18:06 PM
```On Feb 13, 7:22=A0pm, Richard Heathfield <r...@see.sig.invalid> wrote:
> spinoza1111wrote:
>
> <snip>
>
> I see you've ditched malloc.h, so here are my next two observations:

"When everything is ended, you come." - Shakespeare, Henry IV part 2

....dishonestly, like Falstaff, seeking glory. I find it hard to
believe that you've been keeping grave observations in reserve, since
you found no bugs, and would have been as my arch-enemy happy to do so
(stylistic observations about pseudo-portability don't count, and
there were several juicy bugs, none of which you were able to find).
>
> > // Calculate string length
> > //
> > //
> > long strLength(char *strInstring)
> > {
> > =A0 =A0 char *ptrInstring;
> > =A0 =A0 for (ptrInstring =3D strInstring; *ptrInstring; ptrInstring++);
> > =A0 =A0 return ptrInstring - strInstring;
> > }
>
>
> long strLength(const char *s)
> {
> =A0 =A0long len =3D 0;
> =A0 =A0while(*s++) ++len;
> =A0 =A0return len;
>
> }

I'm massively underwhelmed. It's "simpler" only in having fewer
characters in the source code, and this isn't what we mean by
simplicity; mathematics isn't "simple and readable" in the way we

Integrating the increment of s with the test is what you would call
"confusing code" if anyone other than you'd written it, because you're
a narcissist. It defeats what purpose there is in the C for loop,
which was to disambiguate the three parts of a loop. It did so poorly,

If you can write "len", you can write "length". "len" could be
anything.

Initializing len in its declaration-definition will not even compile
on some C compilers. I thought you wrote portable code. Oh well.

OK, how many errors do we have in your code, if we use your own thug's
standard for errors as "I don't like it?"

Three.

>
> Other suggested improvements: (a) use an unsigned type, such as unsigned
> long (strings might have 0 length, but they can never be negatively
> long); and (b) drop the function completely, in favour of strlen.

Oh, I dunno. Some strings of nonsense (such as yours) should never
have been typed and have what we might call negative entropy, and we
could represent this as a negative string length.

>
> <snip>
>
> > =A0 =A0 if (!*strTarget)
> > =A0 =A0 {
> > =A0 =A0 =A0 =A0 printf("Error in calling replace(): target can't be nul=
l");
> > =A0 =A0 =A0 =A0 abort();
>
> If you intend this to be a general purpose solution, calling abort() is
> not a good idea.

Yes. Monkey and typewriter, but yes. However, you may have noticed if
you were awake that the code is "packaged" as a proof of concept (the
concept being "writing a replace even outside the string library is
not rocket science, but it is too hard for Republicans and Limey
sods").

And Lo! Heathfield labors mightily to stay inside the Game:
But the combat is already over, to each side's shame or fame:
The shadows lengthen on the pitch, he cries play up for me
And so the Combatants turn once more to their game of reading C.
The crowd is hush'd, and expectant Pall falls upon one and all
And then the mighty Heathfield upon the Gods doth cry his call
And show us his solution, alas, 'tis...Trivi-all.
He's missed the point, the boat, the bus, and the London train
If this were not so funny it would give the Gentle pain:
He's rolled offside off the Pitch and onto the green grass
To tell me how to write a string length function, Lord, what an Ass!
In tones of grave and pompous Preaching he groans Admonishment:
Expecting us his Flock to receive him with Astonishment:
But alas in the remains of a day so drear there is silence in the
Crowd:
And then a Titter, then a Chortle, third a Guf-faw, then both long and
Loud
Resounds the Laughter of the Gods which dismays all Philistines
From Hill, to Dale, to Glen, to Pale, are hearden its load Screams:
And so it is, and was, and ever it shall be cried
That Heathfield has struck out and has kicked the ball, offside.

Oh, that was Lofty.

>
> <snip>
>
> --
> Richard Heathfield <http://www.cpax.org.uk>
> Email: -http://www. +rjh@
> "Usenet is a strange place" - dmr 29 July 1999
> Sig line vacant - apply within

```
 0
spinoza1111 (3246)
2/13/2010 12:20:19 PM
```Tim Streater <timstreater@waitrose.com> writes:

> On 13/02/2010 10:30, spinoza1111 wrote:
>
>> My code is hard to read, it is said (on dit). In a sense, it is. I
>> find it hard to read at times myself.
>
> Then it's shitty code, pure and simple.

Some of the best code I have dealt with turned out to need a while to
acclimatise to.

One should NEVER program to the lowest common denominator such as Bill
Cunningham for example.

There appears to be some strange opinion here that ALL code is
constantly being read by hundreds of people as the brilliance of your
output is ported and modded to 1000s of platforms and new projects. It
isn't. Far better to have a small routine complex but EFFICIENT that
"easy to read" and a dog. Complex? Comment it.

--
"Avoid hyperbole at all costs, its the most destructive argument on
the planet" - Mark McIntyre in comp.lang.c
```
 0
rgrdev_ (1097)
2/13/2010 12:23:23 PM
```On Feb 13, 8:18=A0pm, Richard <rgrd...@gmail.com> wrote:
> Richard Heathfield <r...@see.sig.invalid> writes:
> >spinoza1111wrote:
> > <snip>
>
> > I see you've ditched malloc.h, so here are my next two observations:
>
> >> // Calculate string length
> >> //
> >> //
> >> long strLength(char *strInstring)
> >> {
> >> =A0 =A0 char *ptrInstring;
> >> =A0 =A0 for (ptrInstring =3D strInstring; *ptrInstring; ptrInstring++)=
;
> >> =A0 =A0 return ptrInstring - strInstring;
> >> }
>
>
> > long strLength(const char *s)
> > {
> > =A0 =A0long len =3D 0;
> > =A0 =A0while(*s++) ++len;
> > =A0 =A0return len;
> > }
>
> An unnecessary increment on every loop. Potentially expensive for long
> blocks. Nilges might be faster in many cases.

Whoa, missed that. Thanks for pointing this out. The count is four.
There is no joy, I am certain, in Mudville.

```
 0
spinoza1111 (3246)
2/13/2010 12:35:07 PM
```On Feb 13, 8:23=A0pm, Richard <rgrd...@gmail.com> wrote:
> Tim Streater <timstrea...@waitrose.com> writes:
> > On 13/02/2010 10:30,spinoza1111wrote:
>
> >> My code is hard to read, it is said (on dit). In a sense, it is. I
> >> find it hard to read at times myself.
>
> > Then it's shitty code, pure and simple.
>
> Some of the best code I have dealt with turned out to need a while to
> acclimatise to.
>
> One should NEVER program to the lowest common denominator such as Bill
> Cunningham for example.
>
> There appears to be some strange opinion here that ALL code is
> constantly being read by hundreds of people as the brilliance of your
> output is ported and modded to 1000s of platforms and new projects. It
> isn't. Far better to have a small routine complex but EFFICIENT that
> "easy to read" and a dog. Complex? Comment it.

"Wisdom crieth without; she uttereth her voice in the streets: She
crieth in the chief place of concourse, in the openings of the gates:
in the city she uttereth her words, saying, How long, ye simple ones,
will ye love simplicity?"

>
> --
> "Avoid hyperbole at all costs, its the most destructive argument on
> the planet" - Mark McIntyre in comp.lang.c

```
 0
spinoza1111 (3246)
2/13/2010 12:39:24 PM
```On Feb 13, 8:39=A0pm, spinoza1111 <spinoza1...@yahoo.com> wrote:
> On Feb 13, 8:23=A0pm, Richard <rgrd...@gmail.com> wrote:
>
>
>
>
>
> > Tim Streater <timstrea...@waitrose.com> writes:
> > > On 13/02/2010 10:30,spinoza1111wrote:
>
> > >> My code is hard to read, it is said (on dit). In a sense, it is. I
> > >> find it hard to read at times myself.
>
> > > Then it's shitty code, pure and simple.
>
> > Some of the best code I have dealt with turned out to need a while to
> > acclimatise to.
>
> > One should NEVER program to the lowest common denominator such as Bill
> > Cunningham for example.
>
> > There appears to be some strange opinion here that ALL code is
> > constantly being read by hundreds of people as the brilliance of your
> > output is ported and modded to 1000s of platforms and new projects. It
> > isn't. Far better to have a small routine complex but EFFICIENT that
> > "easy to read" and a dog. Complex? Comment it.
>
> "Wisdom crieth without; she uttereth her voice in the streets: She
> crieth in the chief place of concourse, in the openings of the gates:
> in the city she uttereth her words, saying, How long, ye simple ones,
> will ye love simplicity?"
>
>
>
>
>
> > --
> > "Avoid hyperbole at all costs, its the most destructive argument on
> > the planet" - Mark McIntyre in comp.lang.c

Looking over some of the other "solutions" to the problem, I note that
some use memcpy unnecessarily.

Whereas here is what I do when I need to create a segment block:

if (!(ptrSegmentStruct =3D
malloc(sizeof(struct TYPsegmentstruct))))
abort();
ptrSegmentStruct->strSegment =3D ptrIndex0;
ptrSegmentStruct->lngSegmentLength =3D
ptrIndex1 - ptrIndex0;
ptrSegmentStruct->ptrNext =3D 0;

Not being burdened with "tools" like memcpy that in many ways want to
think for me, I here am as slick as I can be, for I insert a pointer
to the segment start and its length, whereas other alternate solutions
might do extra mem copies, perhaps into the structure, because "it is
good to use tools and unsafe to reinvent the wheel" and other nursery
maxims of the programming cargo cult.

Of course, to cash-out the final string, we do have to do memory
moves:

for (ptrIndex1 =3D ptrSegmentStruct->strSegment,
lngCount =3D 0;
lngCount < ptrSegmentStruct->lngSegmentLength;
ptrIndex1++, lngCount++, strNew++)
*strNew =3D *ptrIndex1;
if (ptrSegmentStruct->ptrNext
||
ptrIndex2 !=3D 0 && !*ptrIndex2)
for (ptrIndex1 =3D strReplacement;
*ptrIndex1;
ptrIndex1++, ++strNew)
*strNew =3D *ptrIndex1;

Oh I didn't use memcpy. Hey wait a minute, did I remember to put a Nul
at the end?

Whew:

*strNew =3D '\0';
return strNewStart;

In fact, if you have my structure and the replacement string, this
data assembly constitutes a virtual new string which in a large and
integrated program could become a space-saving way to represent a
class of similar strings.

Note that while purporting to do our thinking for us, "tools" let us
down (an English officer in September 1914 defined a "battle" as "that
which takes place at the juncture of two different maps"). memcpy
could lull us into forgetting to add the Nul. Not using it keeps us
awake. More generally, "reinventing the wheel" defines us as men, homo
faber, and are we not men.
```
 0
spinoza1111 (3246)
2/13/2010 12:59:36 PM
```On Feb 13, 6:43=A0pm, Tim Streater <timstrea...@waitrose.com> wrote:
> On 13/02/2010 10:30,spinoza1111wrote:
>
> > My code is hard to read, it is said (on dit). In a sense, it is. I
> > find it hard to read at times myself.
>
> Then it's shitty code, pure and simple.

He had bought a large map representing the sea,
Without the least vestige of land:
And the crew were much pleased when they found it to be
A map they could all understand.

"What's the good of Mercator's North Poles and Equators,
Tropics, Zones, and Meridian Lines?"
So the Bellman would cry: and the crew would reply
"They are merely conventional signs!

"Other maps are such shapes, with their islands and capes!
But we've got our brave Captain to thank:"
(So the crew would protest) "that he's bought us the best--
A perfect and absolute blank!"

(Lewis Carroll, The Hunting of the Snark)
>
> --
> Tim
>
> "That the freedom of speech and debates or proceedings in Parliament
> ought not to be impeached or questioned in any court or place out of
> Parliament"
>
> Bill of Rights 1689

```
 0
spinoza1111 (3246)
2/13/2010 1:35:55 PM
```On 13/02/2010 11:53, spinoza1111 wrote:
> On Feb 13, 6:43 pm, Tim Streater<timstrea...@waitrose.com>  wrote:
>> On 13/02/2010 10:30,spinoza1111wrote:
>>
>>> My code is hard to read, it is said (on dit). In a sense, it is. I
>>> find it hard to read at times myself.
>>
>> Then it's shitty code, pure and simple.
>
> That is the common view. I regard it as self-indulgent. Who says you

The fact that I can write it. The fact that I am (purely for my own
amusement) nearly done with writing an e-mail user-agent (not in C and
not likely to be seen off my own Mac). The fact that at SLAC more than
20 years ago, I wrote a software package (30k lines of C) to control and
gather statistics from a number of similar digital switches, running on
a MicroVAX. Some parts of the code ran on other VAXes (VMS) and IBM
mainframes under VM/CMS.

To do this we:

1) Used the Xerox suite of network protocols (IP not then being in the
ascendency).

2) Adapted a commercial threads microkernel (written in C) to run under
VMS and VM/CMS (note: we had no portability issues with the C). We had
to write a small amount of assembler for each host type (and fix a
number of bugs we found inside VM/CMS, mostly to do with timer handling).

Note also that all the C code written for this project was re-entrant (a
feature heavily used in the project). And we had no problems with that
either.

I could also throw in the assets database and associated front end (not
written in C) done at my last employer before retiring, but I can't be
bothered.

I might also point out that I was with each of my three employers for 15
years and left each voluntarily.

So, all in all, I think it can be said that I can read code.

--
Tim

"That the freedom of speech and debates or proceedings in Parliament
ought not to be impeached or questioned in any court or place out of
Parliament"

Bill of Rights 1689
```
 0
timstreater (945)
2/13/2010 2:21:55 PM
```On 2010-02-13, Tim Streater <timstreater@waitrose.com> wrote:
> On 13/02/2010 10:30, spinoza1111 wrote:
>> My code is hard to read, it is said (on dit). In a sense, it is. I
>> find it hard to read at times myself.

> Then it's shitty code, pure and simple.

Pretty much.  Why did multiple attempts at getting the Nilges string
replacement code debugged fail after hours of effort?  Because it was hard
to read.  Code which is hard to read is hard to maintain.  Code which is
hard to maintain will start buggy.  It will remain buggy despite debugging
efforts.  It will become buggy whenever feature work needs to be done.

This ties in some to the debate about "software engineering".  What would
people think of someone who claimed to be an "engineer", but who designed
bridges so elaborately complicated that no one could figure out which parts

This is why I don't take Nilges seriously when he rants about the design
of C.  He's demonstrated conclusively that he has no clue about competent
design, and someone who can't build even simple programs correctly is not
qualified to comment on any programming language.

-s
--
Copyright 2010, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
```
 0
usenet-nospam (2309)
2/13/2010 4:21:24 PM
```On Feb 14, 12:21=A0am, Seebs <usenet-nos...@seebs.net> wrote:
> On 2010-02-13, Tim Streater <timstrea...@waitrose.com> wrote:
>
> > On 13/02/2010 10:30,spinoza1111wrote:
> >> My code is hard to read, it is said (on dit). In a sense, it is. I
> >> find it hard to read at times myself.
> > Then it's shitty code, pure and simple.
>
> Pretty much. =A0Why did multiple attempts at getting the Nilges string
> replacement code debugged fail after hours of effort? =A0Because it was h=
ard

You're lying: the console output from the current version is at the
end of this response. Also, the next time you start a thread using the
word "efficiency", use a dictionary.

You and Richard Heathfield need to LEAVE. This is because you both
have a track record of LYING in this and other newsgroups because you
are using them DISHONESTLY to advance yourself in a profession for
which you are not qualified.

> to read. =A0Code which is hard to read is hard to maintain. =A0Code which=
is
> hard to maintain will start buggy. =A0It will remain buggy despite debugg=
ing
> efforts. =A0It will become buggy whenever feature work needs to be done.
>
> This ties in some to the debate about "software engineering". =A0What wou=
ld
> people think of someone who claimed to be an "engineer", but who designed
> bridges so elaborately complicated that no one could figure out which par=
ts

I don't claim to be an engineer. Do you, oh finder and sender on of
bugs who could not find the bugs in my code? If I were your manager, I
would in fact be very concerned that you could not do so when to do so
would have scored the points you so pathetically try to score here.

Software engineering is "how to program if you cannot", as Dijkstra
has said. You might need it. I don't. But you are by no stretch of the
imagination, an "engineer". Real engineers don't lie, because in
genuine engineering jobs, as opposed to computing jobs which in many
cases constitute welfare for white males, you lie like you do, you GO
TO JAIL.

>
> This is why I don't take Nilges seriously when he rants about the design
> of C. =A0He's demonstrated conclusively that he has no clue about compete=
nt
> design, and someone who can't build even simple programs correctly is not
> qualified to comment on any programming language.

You're lying. This thread in fact makes me very glad that I am no
longer a programmer, for commencing with the election of Reagan, I saw
the entry of people like you destroy workgroups and companies. I saw
the hiring of unqualified people (some with psychology in place of
compsci degrees, and, worse, zero interest in autodidactic computer
science) destroy the Mountain View site of Bell Northern Research.
Structured walkthroughs became savage and inane by turns, unqualified
people took trips and junkets, and around Christmas of 1985, while I
was working late on a 24 bit version of the SL.1 compiler, a holiday
party in another part of the building was ending in property damage
and drunken fistfights.

I saw people like you (including self-hating homosexuals) destroy
Catapult Software Training's Chicago office with your type of lies, as
well.

For let us not speak falsely now the hour is much too late.

You're lying. The code I posted and in which I have fixed all problems
reported to date has worked better than anything you've posted, and
YOU NEVER FIXED the %s bug that was in the code that started this
discussion! The other code samples you posted contained bugs, but your
rule seems to be "my mistakes must be forgiven, the 'heap' is a DOS
term, but if anyone I don't like, or need to ass-kiss, makes a
mistake, I'll be on his errors like a fly on shit".

Anyone here can go to the code a few posts above and download it,
compile and run it to get the following console output to verify that
you are lying, as you lied maliciously and libelously about Herb
Schildt, damaging his reputation in order to create a dishonest
impression that you are a qualified programmer, which YOU ARE NOT.

I have carefully documented how the Google Groups browser may make
minor modifications which a competent technician, WHICH YOU ARE NOT,
can fix them. Whereas you created a new thread, misspelling its title,
that started with a lie and here, continues with a lie. The code you
posted is crap and doesn't solve the problem which was to do the
replace() without using string.h.

You talk about "software quality" in the corporate register which must
of necessity take ownership of the term while not ever admitting that
the speaker-writer may not know his ass from a hole in the ground.
This is the register of people who do not know their trade and who are
complete frauds.

Whereas I am discussing a real programming problem, and working with
the real professionals here, like Ike Naar, Santosh, IO_x, and
Bacarisse, I have been able AS INTENDED to debug collaboratively
showing twerps like you (who isn't, apparently, trusted to actually
code real software at his job) how it's done. I've got the code into
the state it's in, no thanks to you, where it does, I believe, the
minimal amount of work without requiring the tables that more advanced
algorithms require.

This display of competence and professionalism, by someone returning
to C after almost 20 years, along with the competence and
professionalism of Naar, Santosh, et al., has exposed you and you are
lashing out with lies, Lash Larue.

The jig is up.

Replace

Replace "111123" by "ono" in
"1111123bbb1111123bbb11123bb11111231111112111111123"
Expect "1onobbb1onobbb11123bb1ono1111112111ono":
"1onobbb1onobbb11123bb1ono1111112111ono"
Replacements expected: 4: replacements: 4

Replace "111123" by "ono" in "bbb1111123bbbbb"
Expect "bbb1onobbbbb":
"bbb1onobbbbb"
Replacements expected: 1: replacements: 1

Replace "stupid error" by "miracle" in "a stupid error"
Expect "a miracle":
"a miracle"
Replacements expected: 1: replacements: 1

Replace "stupid" by "miracle" in "a stupid error"
Expect "a miracle error":
"a miracle error"
Replacements expected: 1: replacements: 1

Replace "the stupid error" by "a miracle" in "the stupid error"
Expect "a miracle":
"a miracle"
Replacements expected: 1: replacements: 1

Replace "the" by "a" in "the miracle"
Expect "a miracle":
"a miracle"
Replacements expected: 1: replacements: 1

Replace "snirpKamunkle" by "e" in "a miraclsnirpKamunkle"
Expect "a miracle":
"a miracle"
Replacements expected: 1: replacements: 1

Replace "a miracle" by "" in "a miraclesnirpKamunkle"
Expect "snirpKamunkle":
"snirpKamunkle"
Replacements expected: 1: replacements: 1

Replace "a miracle" by "" in " a miraclesnirpKamunkle"
Expect " snirpKamunkle":
" snirpKamunkle"
Replacements expected: 1: replacements: 1

Replace "a miracle" by "" in " a miraclesnirpKamunklea miraclea
miracle"
Expect " snirpKamunkle":
" snirpKamunkle"
Replacements expected: 3: replacements: 3

Replace "a miracle" by "" in "a miracle a miraclesnirpKamunkle a
Miraclea miraclea miracle"
Expect " snirpKamunkle a Miracle":
" snirpKamunkle a Miracle"
Replacements expected: 4: replacements: 4

Replace "stupid error" by "miracle" in "a stupid errord"
Expect "a miracled":
"a miracled"
Replacements expected: 1: replacements: 1

Replace "stupid error" by "miracle" in "a stupid errod"
Expect "a stupid errod":
"a stupid errod"
Replacements expected: 0: replacements: 0

Replace "stupid error" by "miracle" in "a sstupid error"
Expect "a smiracle":
"a smiracle"
Replacements expected: 1: replacements: 1

Replace "stupid error" by "miracle" in "a stupid errorstupid error"
Expect "a miraclemiracle":
"a miraclemiracle"
Replacements expected: 2: replacements: 2

Replace "stupid error" by "miracle" in "a stupid error stupiderror"
Expect "a miracle stupiderror":
"a miracle stupiderror"
Replacements expected: 1: replacements: 1

Replace "b" by "a" in "bbbbbbbbbb"
Expect "aaaaaaaaaa":
"aaaaaaaaaa"
Replacements expected: 10: replacements: 10

Replace "%s" by "Cthulu" in "In the halls of R'yleh great %s lies
dreaming"
Expect "In the halls of R'yleh great Cthulu lies dreaming":
"In the halls of R'yleh great Cthulu lies dreaming"
Replacements expected: 1: replacements: 1

Replace "%s" by "Cthulu" in "%s%s%s%s%s%s"
Expect "CthuluCthuluCthuluCthuluCthuluCthulu":
"CthuluCthuluCthuluCthuluCthuluCthulu"
Replacements expected: 6: replacements: 6

Replace "ana" by "oat" in "banana"
Expect "boatna":
"boatna"
Replacements expected: 1: replacements: 1

Replace "stupid error" by "+" in " a stupid errorstupid errorHeystupid
errors"
Expect " a ++Hey+s":
" a ++Hey+s"
Replacements expected: 3: replacements: 3

Replace "foo bar" by "bas" in "foo barfoo barf"
Expect "basbasf":
"basbasf"
Replacements expected: 2: replacements: 2

Replace "ba" by "ba" in "abab"
Expect "abab":
"abab"
Replacements expected: 1: replacements: 1

Replace "bab" by "boop" in "abab"
Expect "aboop":
"aboop"
Replacements expected: 1: replacements: 1

Replace "ana" by "ono" in "banana"
Expect "bonona":
"bonona"
Replacements expected: 1: replacements: 1

Replace "x" by "b" in "a"
Expect "a":
"a"
Replacements expected: 0: replacements: 0

Replace "x" by "b" in "x"
Expect "b":
"b"
Replacements expected: 1: replacements: 1

Replace "egregious" by "egregious" in "egregious"
Expect "egregious":
"egregious"
Replacements expected: 1: replacements: 1

Replace "egregious" by "x" in "egregious"
Expect "x":
"x"
Replacements expected: 1: replacements: 1

Testing complete: check output carefully: "Assertion failed" should
not occur!
```
 0
spinoza1111 (3246)
2/13/2010 5:22:35 PM
```On Feb 13, 10:21=A0pm, Tim Streater <timstrea...@waitrose.com> wrote:
> On 13/02/2010 11:53,spinoza1111wrote:
>
> > On Feb 13, 6:43 pm, Tim Streater<timstrea...@waitrose.com> =A0wrote:
> >> On 13/02/2010 10:30,spinoza1111wrote:
>
> >>> My code is hard to read, it is said (on dit). In a sense, it is. I
> >>> find it hard to read at times myself.
>
> >> Then it's shitty code, pure and simple.
>
> > That is the common view. I regard it as self-indulgent. Who says you
>
> The fact that I can write it. The fact that I am (purely for my own
> amusement) nearly done with writing an e-mail user-agent (not in C and
> not likely to be seen off my own Mac). The fact that at SLAC more than
> 20 years ago, I wrote a software package (30k lines of C) to control and
> gather statistics from a number of similar digital switches, running on
> a MicroVAX. Some parts of the code ran on other VAXes (VMS) and IBM
> mainframes under VM/CMS.
>
> To do this we:
>
> 1) Used the Xerox suite of network protocols (IP not then being in the
> ascendency).
>
> 2) Adapted a commercial threads microkernel (written in C) to run under
> VMS and VM/CMS (note: we had no portability issues with the C). We had
> to write a small amount of assembler for each host type (and fix a
> number of bugs we found inside VM/CMS, mostly to do with timer handling).
>
> Note also that all the C code written for this project was re-entrant (a
> feature heavily used in the project). And we had no problems with that
> either.
>
> I could also throw in the assets database and associated front end (not
> written in C) done at my last employer before retiring, but I can't be
> bothered.
>
> I might also point out that I was with each of my three employers for 15
> years and left each voluntarily.
>
> So, all in all, I think it can be said that I can read code.

Doesn't follow, at all. In fact, many programmers have attention-
hyperactivity disorder that makes them prefer to write new code rather
than make the longer, more focused, and more empathic effort to read,
tolerate, connect-with and finally understand The Code of the Other.

When I started in programming, in fact, I was struck by the sheer
number of nervous disorders and tics of my coworkers, although they
were a refreshing change of pace from my own. I was especially struck
by how many programmers seemed to have math anxiety. I taught a C
class in 1990: one commenter said "he uses too much math", which was
just nuts if you ask me.

Most famously Larry Ellison, the CEO of Oracle, had by his own account
AHD and by his own account succeeded at a famously difficult Fortran
class at the University of Illinois because as opposed to other
"boring" classes, he could focus for short but sharp amounts of time
on writing new code, which then as now is the focus in university
programming courses. I had the same experience at roughly the same
time, writing a bug free machine language program as my first program
ever on a freezing night at Northwestern's library.

But I found it harder to tolerate The Code of the Other, in my case
because the first Code of the Other I encountered was genuinely poor
code. I had to cultivate the skill at Bell Northern Research where I
inherited a mass of compilers and tools, that were written by
extremely bright people in Ottawa (celebrated in a book, now out of
print, called Knights of the New Technology).

This is why I have always been skeptical of the unprovable claim that
code (or English text) is "hard to read", which is phrased as an
innate property of the text, and not of the relation of the reader to
the text. It is based on a primitive, lower middle class, almost
magical "theory" of the text in which the text, like the Bible of the
fundamentalist, must give a singular answer, in the style and
shibboleths of the reader, and if it does not, then it's the author's
fault.

In fine, I really don't care that you've been a faithful employee of
three firms and written a lotta code. That may be admirable, and
thanks for sharing, but it doesn't make you an authority on software
>
> --
> Tim
>
> "That the freedom of speech and debates or proceedings in Parliament
> ought not to be impeached or questioned in any court or place out of
> Parliament"
>
> Bill of Rights 1689

```
 0
spinoza1111 (3246)
2/13/2010 5:36:34 PM
```Richard Heathfield <rjh@see.sig.invalid> writes:
>long strLength(const char *s)

ISO C 90 might contain a provision stating that:

�The implementation may further restrict the
significance of an external name (an identifier that has
external linkage) to six characters and may ignore
distinctions of alphabetical case for such names�.

(This text was copied from a draft, but I remember
having read this in the ANSI document, too.)

```
 0
ram (2986)
2/13/2010 5:47:53 PM
```Richard <rgrdev_@gmail.com> writes:

> Tim Streater <timstreater@waitrose.com> writes:
>
>> On 13/02/2010 10:30, spinoza1111 wrote:
>>
>>> My code is hard to read, it is said (on dit). In a sense, it is. I
>>> find it hard to read at times myself.
>>
>> Then it's shitty code, pure and simple.
>
> Some of the best code I have dealt with turned out to need a while to
> acclimatise to.
>
> One should NEVER program to the lowest common denominator such as Bill
> Cunningham for example.
>
> There appears to be some strange opinion here that ALL code is
> constantly being read by hundreds of people as the brilliance of your
> output is ported and modded to 1000s of platforms and new projects. It
> isn't. Far better to have a small routine complex but EFFICIENT that
> "easy to read" and a dog. Complex? Comment it.

All code has at least one important reader -- the author.  What odds
do you give that version 11 of this code (if I've counted correctly) is
finally bug free?

--
Ben.
```
 0
ben.usenet (6790)
2/13/2010 5:59:01 PM
```spinoza1111 wrote:
> On Feb 13, 7:22 pm, Richard Heathfield <r...@see.sig.invalid> wrote:
>> spinoza1111wrote:
>>
>> <snip>
>>
>> I see you've ditched malloc.h, so here are my next two observations:
>
> "When everything is ended, you come." - Shakespeare, Henry IV part 2

Yeah. And at *this* point, when you think you've fixed it all up just
so, it's still easy to suggest improvements in your code.

>
> ....dishonestly, like Falstaff, seeking glory.

The glory involved in pointing out improvements in your code is about at
the same level as the glory involved in peeling a banana.

> I find it hard to
> believe that you've been keeping grave observations in reserve,

And indeed I haven't. When I saw a copy of the code that demonstrated
you'd learned from my first observation, I looked at the code
sufficiently closely to find a couple more observations. If you show any
sign of learning from those, I'll offer some more. But I don't save them
up. Experience teaches me that you are not a quick learner.

> since you found no bugs,

I haven't looked yet.

> and would have been as my arch-enemy

I'm not your arch-enemy. You are.

> happy to do so
> (stylistic observations about pseudo-portability don't count, and
> there were several juicy bugs, none of which you were able to find).

<shrug> I didn't look.

Now let's see if you were paying attention.

>>> // Calculate string length
>>> //
>>> //
>>> long strLength(char *strInstring)
>>> {
>>>     char *ptrInstring;
>>>     for (ptrInstring = strInstring; *ptrInstring; ptrInstring++);
>>>     return ptrInstring - strInstring;
>>> }
>>
>> long strLength(const char *s)
>> {
>>    long len = 0;
>>    while(*s++) ++len;
>>    return len;
>>
>> }
>
> I'm massively underwhelmed.

Yeah, I know.

> It's "simpler" only in having fewer
> characters in the source code,

I should have realised that its lack of verbosity would appear to you to
be a weakness rather than a strength.

> and this isn't what we mean by
> simplicity; mathematics isn't "simple and readable" in the way we

Good programming is made up of many good decisions.

> Integrating the increment of s with the test is what you would call
> "confusing code" if anyone other than you'd written it,

No, it's a standard C idiom. You'll find it in K&R, for example.

> because you're a narcissist.

Ah, you've been taught another new word. Here's yet another: projection.

> It defeats what purpose there is in the C for loop,
> which was to disambiguate the three parts of a loop. It did so poorly,

But I didn't even use a for loop! It's not necessary here.

> If you can write "len", you can write "length". "len" could be
> anything.

It could, for example, be length.

> Initializing len in its declaration-definition will not even compile
> on some C compilers.

Rubbish. Any conforming implementation is required to support
initialisation syntax.

> I thought you wrote portable code. Oh well.

I do. You don't know what it means.

<nonsense snipped>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
```
 0
rjh (10791)
2/13/2010 6:15:17 PM
```On 2010-02-13, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
> Richard <rgrdev_@gmail.com> writes:
>> There appears to be some strange opinion here that ALL code is
>> constantly being read by hundreds of people as the brilliance of your
>> output is ported and modded to 1000s of platforms and new projects. It
>> isn't. Far better to have a small routine complex but EFFICIENT that
>> "easy to read" and a dog. Complex? Comment it.

> All code has at least one important reader -- the author.  What odds
> do you give that version 11 of this code (if I've counted correctly) is
> finally bug free?

The assumption that efficient code must be hard to read, or that efficiency
is likely to make code hard to read, is unsupported.

The problem with the Nilges string replace program is largely that the design
is gratuitously complicated.  However, simply choosing remotely reasonable
names for the ptrIndex* variables would probably have addressed a great deal
of it.  If you're constantly flipping back to see what something points to,
that suggests that you're doing it wrong.

Furthermore, the performance of his algorithm is likely to be unbelievably
bad, because on most systems, the overhead of malloc/free pairs is noticably
larger than the overhead of searching an entire string several times.  So it's
not even actually efficient.

In general, you should write things for clarity first.  Once you have
something which clearly works and is well-understood and tested, THEN it
is time to start thinking about such questions as "is it fast enough".  If
not, then you profile to find out where the time goes.  THEN you see whether
it's time to rewrite something.

But even if you're writing for efficiency, it's not usually necessary to
write unclear code.  Contrary to popular belief, the execution time of code
is not harmed by indentation, decent variable naming conventions, or the
like.  On modern compilers, intermediate variables are likely free too, so
writing for clarity by, say, giving a name to a particular intermediate
value, doesn't usually hurt performance.

As is usually the case, "Richard" (no last name) is apparently trolling,
stupid, or both.

-s
--
Copyright 2010, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
```
 0
usenet-nospam (2309)
2/13/2010 6:17:06 PM
```spinoza1111 wrote:
> On Feb 13, 8:18 pm, Richard <rgrd...@gmail.com> wrote:
>> Richard Heathfield <r...@see.sig.invalid> writes:
>>> spinoza1111wrote:
>>> <snip>
>>> I see you've ditched malloc.h, so here are my next two observations:
>>>> // Calculate string length
>>>> //
>>>> //
>>>> long strLength(char *strInstring)
>>>> {
>>>>     char *ptrInstring;
>>>>     for (ptrInstring = strInstring; *ptrInstring; ptrInstring++);
>>>>     return ptrInstring - strInstring;
>>>> }
>>> long strLength(const char *s)
>>> {
>>>    long len = 0;
>>>    while(*s++) ++len;
>>>    return len;
>>> }
>> An unnecessary increment on every loop. Potentially expensive for long
>> blocks. Nilges might be faster in many cases.
>
> Whoa, missed that.

and use the standard library, which will wipe the floor with both versions.

> Thanks for pointing this out. The count is four.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
```
 0
rjh (10791)
2/13/2010 6:17:35 PM
```On 2010-02-13, Richard Heathfield <rjh@see.sig.invalid> wrote:
> spinoza1111 wrote:
>> On Feb 13, 8:18 pm, Richard <rgrd...@gmail.com> wrote:
>>> Richard Heathfield <r...@see.sig.invalid> writes:
>>>> long strLength(const char *s)
>>>> {
>>>>    long len = 0;
>>>>    while(*s++) ++len;
>>>>    return len;
>>>> }

>>> An unnecessary increment on every loop. Potentially expensive for long
>>> blocks. Nilges might be faster in many cases.

>> Whoa, missed that.

> You also missed my advice (upthread) to ditch the function completely
> and use the standard library, which will wipe the floor with both versions.

Typically, yes.

That said, I do like the idiom
size_t lenstr(char *string) {
char *end = string;
while (*end++)
;
return end - string;
}

Not that it's likely to make a noticeable difference.  Or that it's likely
worth it when obviously the standard library one will be fine.

-s
--
Copyright 2010, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
```
 0
usenet-nospam (2309)
2/13/2010 6:19:56 PM
```Tim Streater wrote:
> On 13/02/2010 11:53, spinoza1111 wrote:
>> On Feb 13, 6:43 pm, Tim Streater<timstrea...@waitrose.com>  wrote:
>>> On 13/02/2010 10:30,spinoza1111wrote:
>>>
>>>> My code is hard to read, it is said (on dit). In a sense, it is. I
>>>> find it hard to read at times myself.
>>>
>>> Then it's shitty code, pure and simple.
>>
>> That is the common view. I regard it as self-indulgent. Who says you
>
> The fact that I can write it.

I doubt whether anyone would question it, other than spinoza1111 and the
trolls, and their opinion is of no moment.

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
```
 0
rjh (10791)
2/13/2010 6:21:04 PM
```Stefan Ram wrote:
> Richard Heathfield <rjh@see.sig.invalid> writes:
>> long strLength(const char *s)
>
>   ISO C 90 might contain a provision stating that:
>
>       �The implementation may further restrict the
>       significance of an external name (an identifier that has
>       external linkage) to six characters and may ignore
>       distinctions of alphabetical case for such names�.
>
>   (This text was copied from a draft, but I remember
>   having read this in the ANSI document, too.)

Yes, it's a lousy name. And it's a lousy function, too. He needs strlen.
He's just too stupid to realise it.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
```
 0
rjh (10791)
2/13/2010 6:25:55 PM
```Seebs <usenet-nospam@seebs.net> writes:
[...]
> That said, I do like the idiom
> 	size_t lenstr(char *string) {
> 		char *end = string;
> 		while (*end++)
> 			;
> 		return end - string;
> 	}
>
> Not that it's likely to make a noticeable difference.  Or that it's likely
> worth it when obviously the standard library one will be fine.

Note that ``end - string'' yields a value of type ptrdiff_t, a signed
type which very likely can't represent all values of type size_t.

This is unlikely to be an issue in practice.  On typical 32-bit
systems, problems show up only for strings longer than 2 gigabytes,
and even then the properties of 2's-complement arithmetic are likely
to result in the correct answer anyway.

But all this analysis, resulting in the conclusion that it will
almost certainly work properly, becomes unnecessary if you just
use strlen().

--
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
```
 0
kst-u (21963)
2/13/2010 8:09:47 PM
```Seebs <usenet-nospam@seebs.net> writes:
> On 2010-02-13, Richard Heathfield <rjh@see.sig.invalid> wrote:
>> spinoza1111 wrote:
>>> On Feb 13, 8:18 pm, Richard <rgrd...@gmail.com> wrote:
>>>> Richard Heathfield <r...@see.sig.invalid> writes:
>>>>> long strLength(const char *s)
>>>>> {
>>>>>    long len = 0;
>>>>>    while(*s++) ++len;
>>>>>    return len;
>>>>> }
>>>> An unnecessary increment on every loop. Potentially expensive for long
>>>> blocks. Nilges might be faster in many cases.
>
>>> Whoa, missed that.
>
>> You also missed my advice (upthread) to ditch the function completely
>> and use the standard library, which will wipe the floor with both versions.
>
> Typically, yes.
>
> That said, I do like the idiom
> 	size_t lenstr(char *string) {
> 		char *end = string;
> 		while (*end++)
> 			;
> 		return end - string;
> 	}
>
> Not that it's likely to make a noticeable difference.  Or that it's likely
> worth it when obviously the standard library one will be fine.

You ran straight into the fencepost. And can we have more const,

Phil, who uses strlen().
--
Any true emperor never needs to wear clothes. -- Devany on r.a.s.f1
```
 0
2/13/2010 11:03:31 PM
```On Sat, 13 Feb 2010 01:25:27 -0800 (PST), spinoza1111
<spinoza1111@yahoo.com> wrote:

>On Feb 13, 2:46=A0am, spinoza1111 <spinoza1...@yahoo.com> wrote:
>...code...
>
>I noticed that in the latest (13 Feb) version of the code, with the
>fix to the one-character replace found by Ben B, there were some file
>nits: two long lines split and blanks at end of continued macro lines.
>
>Let's see if I can get rid of these problems.
>
>Also, I misspoke. The failure to handle Ben's example was caused by an
>earlier change.
>
>Here is the latest code, without the console output.
>

I have no particular interest in this programming challenge,
though I do find some of the commentary amusing.  I thought it
might be of interest to do a code review.  The following is not
an endorsement or a condemnation of the code.  Rather it is an
informal account of code features that are problematic.

Notes on the Nilges code:

(1) At no point is there a comprehensive specification.  A fair
number of corner cases are left up in the air.  These include
overlapping targets, and empty targets.  There is no statement
of error handling strategy.

(2) There are instances of failure to protect against
dereferencing null pointers.  Thus in function strLength the for
loop will dereference a null pointer if argument strInstring is
a null pointer.  Similarly function replace checks strTarget but
not strMaster.  ptrIndex1 is initialized to strMaster.  The
while loop, while(*ptrIndex1), will dereference a null pointer
if strMaster is null.

The test cases do not check for null arguments nor all instances
of empty strings.

(3) The TESTER macro is cumbersome and should be replaced by a
function.

(4) It would be better if the test cases were moved to a
separate file - the plan would be for the main function to read
the test cases from from the test cases file and then compare
the actual test results with the expected test results.

more like coding notes written on the spur of the moment to
remind the coder about what was going on.  There is no statement
of the algorithm being used; the comments often reference
concepts that are not explained.  For example, there is no
precise definition of segment nor of handle.

(6) The commenting format is not well chosen.  The comments
break into the code and vice versa.

(7) The code author uses a bizarre, idiosyncratic, and long
winded variant of Hungarian notation.  It's his privilege.
Unfortunately the long names used are not informative.  For
example, the ptrIndex* variables.  What on earth are they, and
what are their invariants?  The only way to know what they are
is play computer, walk through the code, and reconstruct what
the coder's intent was.

Then there are the ptrSegmentStruct variables.  One has a suffix
of Starts, one of Prev, and one is without a suffix.  Since the
key idea of the implementation is to generate a linked list of
segments, each (except possibly the last) being terminated by
the target string, it turns out that the ptrSegmentStructStarts
refers to the list head, ptrSegmentStruct refers to the current
pointer into the list, and ptrSegmentStructPrev refers to the
previous pointer into the list.  Or perhaps not.

(8) The scheme of allocating space for each segment is mildly
inefficient, but is much better than reallocing space for the
output string.  In any case it is doubtful that execution
efficiency is among the objectives of this exercise.

(9) In some places the code is overly complex.  A case in point
is:

lngNewLength += ptrSegmentStruct->lngSegmentLength +
(ptrIndex2 && !*ptrIndex2
?
lngReplacementLength
:
0);

There are several other instances of unnecessary complexity.
The updating of the never defined Index variables is a case in
point.

(10) Only one of strNew, strNewStart is needed.

(11) In conclusion, it is difficult to determine whether the
code works correctly because the design is not spelled out, the
variables are not properly documention, the testing framework is
inadequate, and the baroque nomeclature and coding complicate
analysis.

Richard Harter, cri@tiac.net
http://home.tiac.net/~cri, http://www.varinoma.com
Infinity is one of those things that keep philosophers busy when they
could be more profitably spending their time weeding their garden.
```
 0
cri (1432)
2/13/2010 11:05:12 PM
```"Seebs" <usenet-nospam@seebs.net> wrote in message
news:slrnhndrhg.3ec.usenet-nospam@guild.seebs.net...

[...]

> That said, I do like the idiom
> size_t lenstr(char *string) {
> char *end = string;
> while (*end++)
> ;
> return end - string;
> }
>
> Not that it's likely to make a noticeable difference.  Or that it's likely
> worth it when obviously the standard library one will be fine.

I believe that you have a bug in that code Seebs. Perhaps you meant
_____________________________________________________
size_t
xstrlen(char const* string)
{
char const* end = string;
while (*end) ++end;
return end - string;
}
_____________________________________________________

?

```
 0
no6 (2828)
2/13/2010 11:23:29 PM
```On 2010-02-13, Chris M. Thomasson <no@spam.invalid> wrote:
> I believe that you have a bug in that code Seebs.

Extremely likely.

This is one of the reasons I rely on the standard library -- my success rate
in avoiding fencepost errors is slightly *less* than chance.  I'm not actually
very good at this stuff, which is why I spend so much time thinking about how
to do it better.

-s
--
Copyright 2010, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
```
 0
usenet-nospam (2309)
2/13/2010 11:35:51 PM
```"Seebs" <usenet-nospam@seebs.net> wrote in message
news:slrnhn628c.o3u.usenet-nospam@guild.seebs.net...
> This may have gotten buried given that it started in a Nilges thread,
> but it's actually pretty interesting.
>
> There was some discussion of algorithms to perform the task:
> Inputs:  target string, replacement string, original string
> Output:  a newly-allocated string containing the original
>   string with each copy of the target string replaced with the
>   replacement string.
>
> Here's a hunk of mine:
>
>        for (count = 0, t = strstr(target, in); t && *t; t = strstr(t, in))
> {
>                ++count;
>                t += inlen;
>        }
>
> Here's a hunk of another one:
>
>>     ptrIndex1 = strMaster;
>>     while(*ptrIndex1)

>
> These hunks are essentially performing the same part of the core loop;
> find the next occurrence of the target string in the original string.

I've looked at both. The first is easier on the eye, but I still can't
figure out what it does. You say, it finds the *next* occurence of the
target, why a loop then?

> The second one was written by Edward Nilges ("spinoza1111").  He offers
> in its defense the assertion that it's the "best" algorithm.  (Nevermind
> that it's got a bug; the bug could be fixed easily.)

You can't really compare these (assuming they really do do the same thing);
your code uses some presumably tried and tested library function (strstr) to
do the tricky part, so you're comparing a *call* to that function to an
experimental *implementation* of it. That doesn't sound fair..

> it is, before trying to optimize.  You may, or may not, be able to
> outperform
> a given library's implementation of strstr().

The efficiency varies. On my lccwin32 and DMC compilers, the time to find an
"A" string, in a string consisting entirely of As, seems to depend on the
length of the string it's searching (perhaps it's doing a strlen() first?).
On gcc it's instant.

(I came across the problem in a related function strchr(), in Malcolm's
Minibasic program, where it had the effect, on large input files, of slowing
down the interpreter from 80K lines per second to about 2K. Replacing the
strchr() call with one line of custom code (I think it was just looking for
next EOL), fixed that.)

--
Bartc

```
 0
bartc (786)
2/14/2010 1:10:53 AM
```Seebs wrote:
> On 2010-02-13, Chris M. Thomasson <no@spam.invalid> wrote:
>> I believe that you have a bug in that code Seebs.
>
> Extremely likely.
>
> This is one of the reasons I rely on the standard library -- my success rate
> in avoiding fencepost errors is slightly *less* than chance.  I'm not actually
> very good at this stuff, which is why I spend so much time thinking about how
> to do it better.
>
> -s

The humility is a good touch. You can use mine.

size_t Strlen(char *s)
{
size_t l = 0;
if (s) while (*s++) l++;
return l;
}

--
Joe Wright
"If you rob Peter to pay Paul you can depend on the support of Paul."
```
 0
joewwright (1738)
2/14/2010 1:40:12 AM
```On 2010-02-14, bartc <bartc@freeuk.com> wrote:
> I've looked at both. The first is easier on the eye, but I still can't
> figure out what it does. You say, it finds the *next* occurence of the
> target, why a loop then?

Because it finds the next occurrence repeatedly until there's no more.

> You can't really compare these (assuming they really do do the same thing);
> your code uses some presumably tried and tested library function (strstr) to
> do the tricky part, so you're comparing a *call* to that function to an
> experimental *implementation* of it. That doesn't sound fair..

I think it's extremely fair, because it highlights the flaw in his "I
refuse to use the library functions" attitude.

Agreed that there are cases where there's reasons not to do that.

-s
--
Copyright 2010, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
```
 0
usenet-nospam (2309)
2/14/2010 2:02:21 AM
```On Feb 14, 1:59=A0am, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
> Richard <rgrd...@gmail.com> writes:
> > Tim Streater <timstrea...@waitrose.com> writes:
>
> >> On 13/02/2010 10:30,spinoza1111wrote:
>
> >>> My code is hard to read, it is said (on dit). In a sense, it is. I
> >>> find it hard to read at times myself.
>
> >> Then it's shitty code, pure and simple.
>
> > Some of the best code I have dealt with turned out to need a while to
> > acclimatise to.
>
> > One should NEVER program to the lowest common denominator such as Bill
> > Cunningham for example.
>
> > There appears to be some strange opinion here that ALL code is
> > constantly being read by hundreds of people as the brilliance of your
> > output is ported and modded to 1000s of platforms and new projects. It
> > isn't. Far better to have a small routine complex but EFFICIENT that
> > "easy to read" and a dog. Complex? Comment it.
>
> All code has at least one important reader -- the author. =A0What odds
> do you give that version 11 of this code (if I've counted correctly) is
> finally bug free?

This isn't a game, Ben. We can play that stupid game with any code if
the game is to target people, Richard posted a technical foul with s+
+.

However, I am not going to waste your time arguing that my code is
"readable". It's not one I can win if you can't really read code and,
like most programmers I've met, are in fact underqualified. I don't
think you are, but I do think many people here are.

So perhaps the code is unreadable...to you.
>
> --
> Ben.

```
 0
spinoza1111 (3246)
2/14/2010 4:20:25 AM
```Joe Wright wrote:
> Seebs wrote:
>> On 2010-02-13, Chris M. Thomasson <no@spam.invalid> wrote:
>>> I believe that you have a bug in that code Seebs.
>>
>> Extremely likely.
>>
>> This is one of the reasons I rely on the standard library -- my
>> success rate
>> in avoiding fencepost errors is slightly *less* than chance.  I'm not
>> actually
>> very good at this stuff, which is why I spend so much time thinking
>> to do it better.
>>
>> -s
>
> The humility is a good touch. You can use mine.
>
> size_t Strlen(char *s)
> {
>    size_t l = 0;
>    if (s) while (*s++) l++;
>    return l;
> }
>

So this is your home-rolled strlen?
--
fred
```
 0
Phred4 (88)
2/14/2010 4:37:08 AM
```On Feb 14, 2:15=A0am, Richard Heathfield <r...@see.sig.invalid> wrote:
> spinoza1111wrote:
> > On Feb 13, 7:22 pm, Richard Heathfield <r...@see.sig.invalid> wrote:
> >> spinoza1111wrote:
>
> >> <snip>
>
> >> I see you've ditched malloc.h, so here are my next two observations:
>
> > "When everything is ended, you come." - Shakespeare, Henry IV part 2
>
> Yeah. And at *this* point, when you think you've fixed it all up just
> so, it's still easy to suggest improvements in your code.
>
>
>
> > ....dishonestly, like Falstaff, seeking glory.
>
> The glory involved in pointing out improvements in your code is about at
> the same level as the glory involved in peeling a banana.

You have suggested no useful improvements.
>
> > I find it hard to
> > believe that you've been keeping grave observations in reserve,
>
> And indeed I haven't. When I saw a copy of the code that demonstrated
> you'd learned from my first observation, I looked at the code
> sufficiently closely to find a couple more observations. If you show any
> sign of learning from those, I'll offer some more. But I don't save them
> up. Experience teaches me that you are not a quick learner.

You're not a teacher. Your Maoist game is to replace teachers with
shouting and slogans. We've seen evidence of your deep incompetence
elsethread, for a programmer with a proper education in computer
science would NEVER copy unpredictable elements into a linked list; a
properly educated programmer would have used a linked list of
pointers. And yet you published this error, which is far more serious
than a typographical error or even a software bug, and far worse than
any of Schildt's typos.

>
> =A0> since you found no bugs,
>
> I haven't looked yet.

Lazy bastard, aren't you. Or perhaps the code is "unreadable" despite
all the work I've done? You know, I discovered a long time ago that
there are two types of people who like to call either texts or code

*  Stupid people employed at positions for which they are not, in
reality, qualified

*  Criminals who find the law unreadable in hopes of copping a plea of
plausible deniability

>
> =A0> and would have been as my arch-enemy
>
> I'm not your arch-enemy. You are.

"He's his own worst enemy" is a bully's catchphrase.
>
> > happy to do so
> > (stylistic observations about pseudo-portability don't count, and
> > there were several juicy bugs, none of which you were able to find).
>
> <shrug> I didn't look.

<The Finger> So why are you commenting at all, not having done your
homework?
>
> Now let's see if you were paying attention.
>
>
>
>
>
> >>> // Calculate string length
> >>> //
> >>> //
> >>> long strLength(char *strInstring)
> >>> {
> >>> =A0 =A0 char *ptrInstring;
> >>> =A0 =A0 for (ptrInstring =3D strInstring; *ptrInstring; ptrInstring++=
);
> >>> =A0 =A0 return ptrInstring - strInstring;
> >>> }
>
> >> long strLength(const char *s)
> >> {
> >> =A0 =A0long len =3D 0;
> >> =A0 =A0while(*s++) ++len;
> >> =A0 =A0return len;
>
> >> }
>
> > I'm massively underwhelmed.
>
> Yeah, I know.
>
> > It's "simpler" only in having fewer
> > characters in the source code,
>
> I should have realised that its lack of verbosity would appear to you to
> be a weakness rather than a strength.
>
> > and this isn't what we mean by
> > simplicity; mathematics isn't "simple and readable" in the way we
> > want. Your code saves one assignment: I'll alert the media.
>
> Good programming is made up of many good decisions.

Incompetent programmers love nursery saws:
It saves them the agony of thought.
Incompetent programmers regress to childhood's laws
A land in which "is" becomes "ought".

>
> > Integrating the increment of s with the test is what you would call
> > "confusing code" if anyone other than you'd written it,
>
> No, it's a standard C idiom. You'll find it in K&R, for example.

Had C been a success as a programming language, an artifact not meant
to be a human language but instead to be at a midpoint between human
language and mathematical formalism, it wouldn't need idiomatic
expressions, and because of its idiotic idioms (including not only pre
and post increment and decrement but also sprintf) years later C was
exposed as unstandardizable and non-deterministic mess.

>
> > because you're a narcissist.
>
> Ah, you've been taught another new word. Here's yet another: projection.
>
> > It defeats what purpose there is in the C for loop,
> > which was to disambiguate the three parts of a loop. It did so poorly,
> > but your use manages to make a bad situation worse.
>
> But I didn't even use a for loop! It's not necessary here.

Yes, it is. Competent programmers do not use the while when the actual
problem is for-like:

*  A for-like loop problem may be defined as one in which the
variables referenced in the loop are not changed by the loop
*  A while-like loop problem may be defined as one in which they
change

You used a while when to express the underlying logic a competent
programmer (one interested in "readability" not to slobs but to other
competent programmers) would have used a for.

>
> > If you can write "len", you can write "length". "len" could be
> > anything.
>
> It could, for example, be length.

But it's not, Len.

>
> > Initializing len in its declaration-definition will not even compile
> > on some C compilers.
>
> Rubbish. Any conforming implementation is required to support
> initialisation syntax.

Here you go again with fraudulent talk, the sort of bullshit that will
land you in court. Because, of course, you know that there are
multiple standards.

>
> =A0> I thought you wrote portable code. Oh well.
>
> I do. You don't know what it means.

What an asshole. Your code can't be pasted and run into common older
implementations. When another's code fails this simple test, you
condemn their competence, but you're supposed to get away with this
shit.

>
> <nonsense snipped>
>
> --
> Richard Heathfield <http://www.cpax.org.uk>
> Email: -http://www. +rjh@
> "Usenet is a strange place" - dmr 29 July 1999
> Sig line vacant - apply within

```
 0
spinoza1111 (3246)
2/14/2010 4:41:10 AM
```On Feb 14, 2:17=A0am, Richard Heathfield <r...@see.sig.invalid> wrote:
> spinoza1111wrote:
> > On Feb 13, 8:18 pm, Richard <rgrd...@gmail.com> wrote:
> >> Richard Heathfield <r...@see.sig.invalid> writes:
> >>> spinoza1111wrote:
> >>> <snip>
> >>> I see you've ditched malloc.h, so here are my next two observations:
> >>>> // Calculate string length
> >>>> //
> >>>> //
> >>>> long strLength(char *strInstring)
> >>>> {
> >>>> =A0 =A0 char *ptrInstring;
> >>>> =A0 =A0 for (ptrInstring =3D strInstring; *ptrInstring; ptrInstring+=
+);
> >>>> =A0 =A0 return ptrInstring - strInstring;
> >>>> }
> >>> long strLength(const char *s)
> >>> {
> >>> =A0 =A0long len =3D 0;
> >>> =A0 =A0while(*s++) ++len;
> >>> =A0 =A0return len;
> >>> }
> >> An unnecessary increment on every loop. Potentially expensive for long
> >> blocks. Nilges might be faster in many cases.
>
> > Whoa, missed that.
>
> You also missed my advice (upthread) to ditch the function completely
> and use the standard library, which will wipe the floor with both version=
s.

Another sign of incompetence you manifest is the unpleasant use of
anthropomorphic terminology to refer to the possibility that you will
use physical violence, from shoving to calling security to something
more serious, to win.
>
> =A0> Thanks for pointing this out. The count is four.
>
> Don't believe everything you read.
>
> --
> Richard Heathfield <http://www.cpax.org.uk>
> Email: -http://www. +rjh@
> "Usenet is a strange place" - dmr 29 July 1999
> Sig line vacant - apply within

```
 0
spinoza1111 (3246)
2/14/2010 4:43:50 AM
```Phred Phungus wrote:
> Joe Wright wrote:
>> Seebs wrote:
>>> On 2010-02-13, Chris M. Thomasson <no@spam.invalid> wrote:
>>>> I believe that you have a bug in that code Seebs.
>>>
>>> Extremely likely.
>>>
>>> This is one of the reasons I rely on the standard library -- my
>>> success rate
>>> in avoiding fencepost errors is slightly *less* than chance.  I'm not
>>> actually
>>> very good at this stuff, which is why I spend so much time thinking
>>> to do it better.
>>>
>>> -s
>>
>> The humility is a good touch. You can use mine.
>>
>> size_t Strlen(char *s)
>> {
>>    size_t l = 0;
>>    if (s) while (*s++) l++;
>>    return l;
>> }
>>
>
> So this is your home-rolled strlen?

Yes Fred, it is. Note it is null pointer safe. Anything else?
--
Joe Wright
"If you rob Peter to pay Paul you can depend on the support of Paul."
```
 0
joewwright (1738)
2/14/2010 5:04:11 AM
```On Feb 14, 2:17=A0am, Seebs <usenet-nos...@seebs.net> wrote:
> On 2010-02-13, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
>
> > Richard <rgrd...@gmail.com> writes:
> >> There appears to be some strange opinion here that ALL code is
> >> constantly being read by hundreds of people as the brilliance of your
> >> output is ported and modded to 1000s of platforms and new projects. It
> >> isn't. Far better to have a small routine complex but EFFICIENT that
> >> "easy to read" and a dog. Complex? Comment it.
> > All code has at least one important reader -- the author. =A0What odds
> > do you give that version 11 of this code (if I've counted correctly) is
> > finally bug free?
>
> The assumption that efficient code must be hard to read, or that efficien=
cy
> is likely to make code hard to read, is unsupported.

Nobody's trying to be efficient. Instead, the goal was to produce, in
a language unfriendly towards encapsulation, an encapsulation. The
practical reason for this was actually to make it easy for a
participant in this discussion to execute some very basic steps so
that she or he could evaluate the code, and either find bugs or verify
that it worked for the accumulating range of test cases, leading to
agreement that the code will work for all cases in the absence of a
formal proof.

Of course, incompetent programmers (like you and Richard) prefer
"snippets" such as your initial example of how not to find %s. As in
Adorno's analysis of Pop music, the snippet *genre* allows you to
weasel out of your mistakes in the same way the conventions of Pop
music allow the musician to suck.

In more vivid terms, I'm conducting a symphony whereas you're a garage
band. It's easier for you to appear "correct" ... to morons. I might
sound like "the Depaul University Symphony" that used in the 1990s to
practice in a space in the old Woolworth's building; their version of
Beethoven's Seventh Symphony sounded like a crowd of musicians pursued
by a bear: but the fact remains, I'm doing something of a different,
and more difficult, *genre*, than your *genre*, which is that of the
corporate drone.

>
> The problem with the Nilges string replace program is largely that the de=
sign
> is gratuitously complicated.

that "find and replace" is two separate problems that should ideally
be factored. However, in the so-called real world, this sort of
pragmatic problem occurs all the time: I can well imagine (having had
thirty years of experience) a situation which demands an unfactored
solution and the absence of string.h: stranger things have happened.

Applied computer science is an unsung and lonely business. Most
corporate "programmers" avoid it, preferring to sit around mocking
other people, because in fact, they are either (like you) uneducated
or poorly auto-didacted in comp sci, or educated in purely theoretical
matters.

Therefore, I set myself to solve the problem of "find and replace no
string.H" in response to your incompetent %s solution, and decided to
work collaboratively by submitting preliminary versions. Some of us
are unafraid of submitting preliminary versions and some of us fix
bugs, rather than mention them with a shit-eating grin as you did wrt
%s.

=A0
> However, simply choosing remotely reasonable
> names for the ptrIndex* variables would probably have addressed a great d=
eal
> of it. =A0If you're constantly flipping back to see what something points=
to,
> that suggests that you're doing it wrong.

Actually, the naming convention makes a beautiful distinction between
unchanging string pointers and work pointers, if I do say so myself.
And I do.

>
> Furthermore, the performance of his algorithm is likely to be unbelievabl=
y
> bad, because on most systems, the overhead of malloc/free pairs is notica=
bly
> larger than the overhead of searching an entire string several times. =A0=
So it's
> not even actually efficient.

You have no evidence for this, and you can't even reason about it
properly; characteristic of incompetent corporate programmers being
the irresponsible use of mathematical terminology without the ability
to do the math.

In fact, we segment the string in my solution into a linked list of
segments:

// ***** Segmentation *****
struct TYPsegmentstruct
{ char * strSegment;
long lngSegmentLength;
struct TYPsegmentstruct * ptrNext; };

Note on Nilges Magyar notation: TYP means "global to the compilation
unit because upper case AND a user-defined type". Instances of TYP are
USR if global or usr if local.

Where m is the number of matches there are in fact m mallocations and
m frees to create and destroy a linked list of segments between
matches. This may be a performance hit, but note that unlike the case
of Richard's "C Unleashed" solution (in which a linked list of
TYPlongAndHorrible can blow up), we can express the worst case
mathematically:

replace("xxxxx ... xxx", "x", "y")

We can then add this to our accumulating "data base" of test cases:

Replace "x" by "y" in "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Expect "yyyyyyyyyyyyyyyyyyyyyyyyyyyy":
"yyyyyyyyyyyyyyyyyyyyyyyyyyyy"
Replacements expected: 28: replacements: 28

We then step through the code for this instance to confirm a
performance bug: for the above example, 28 segments are created each
of zero length.

Although this bug is "only" performance-related, it is in fact a
showstopper for long strings. I'm obliged to you in a quantum/
infinitesimal sense, for you've drawn our attention to this issue,
puke face.

Its solution is elegant: it is to in some way mark the linked list to
show "a run of two or more zero-length segments occurs." The most
elegant way to do this is to sign TYPsegmentstruct.lngSegmentLength
negative.

It means that in the first loop, when we arrive at the malloc, we need
to:

*  Check for a previous segment: this will be a nonzero
ptrSegmentStruct
*  See if it has a zero or negative length
*  If it does:
+ And if the latest segment is zero length, decrement
+ And the latest segment is not zero length, create a new zero
length segment
*  If it doesn't, create a segment
*  If no previous segment exists, create a segment
*  In the assembly loop, skip all linked list nodes with zero or
negative segment lengths

I shall add this change. Your job is to ponder whether there's a risk
that this will add another bug, or whether this is itself buggy.

Oh Finder of Bugs at your day job,
Who can't find the bugs in this code,
Oh Misser of Bugs, oh Elmer, oh Fudd
I hope this isn't too much of a load.

Your garbage, in other words, can be useful in a structured
walkthrough chaired by someone, like me, who's not afraid of you.

Mock on, mock on, Voltaire, Rousseau;
Mock on, mock on; 'tis all in vain!
You throw the sand against the wind,
And the wind blows it back again.

William Blake

"Children are different. Garbage in, food out." - Ted Nelson

>
> In general, you should write things for clarity first. =A0Once you have
> something which clearly works and is well-understood and tested, THEN it
> is time to start thinking about such questions as "is it fast enough". =
=A0If
> not, then you profile to find out where the time goes. =A0THEN you see wh=
ether
> it's time to rewrite something.

Corporatese, for you have no clear idea of clarity apart from pure
phenomena which are private to you. What seems clear is clear. You are
not qualified to speak of mathematical clarity: you've given no
evidence of being able to do math (your ability to disrupt civilized
>
> But even if you're writing for efficiency, it's not usually necessary to
> write unclear code. =A0Contrary to popular belief, the execution time of =
code
> is not harmed by indentation, decent variable naming conventions, or the
> like. =A0On modern compilers, intermediate variables are likely free too,=
so
> writing for clarity by, say, giving a name to a particular intermediate
> value, doesn't usually hurt performance.
>
> As is usually the case, "Richard" (no last name) is apparently trolling,
> stupid, or both.

And note how corporatese allows the sudden shift into racist bullying,
as is the case in real corporations. A Bell Northern Research coworker
who did an install at Northern Telecom in North Carolina noticed how
smoothly, smoothly-spoken NT managers and techs would change their
language in a break room that happened to have a glass window onto the
cafeteria. As soon as they were confident that there were no African
Americans or women present, they would immediately shift from
corporate platitudes to crude remarks about the African American
secretaries in the cafeteria.

I have said before: "troll" is a racist word, and used inaccurately
when the target posts with sincerity, as does Richard.

You and Heathfield can't stand it that there's a growing mass of
posters and lurkers who want you to cease your nonsense.
>
> -s
> --
> Copyright 2010, all wrongs reversed. =A0Peter Seebach / usenet-nos...@see=
bs.nethttp://www.seebs.net/log/<-- lawsuits, religion, and funny picturesht=
tp://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
```
 0
spinoza1111 (3246)
2/14/2010 5:45:54 AM
```On Feb 14, 2:19=A0am, Seebs <usenet-nos...@seebs.net> wrote:
> On 2010-02-13, Richard Heathfield <r...@see.sig.invalid> wrote:
>
> >spinoza1111wrote:
> >> On Feb 13, 8:18 pm, Richard <rgrd...@gmail.com> wrote:
> >>> Richard Heathfield <r...@see.sig.invalid> writes:
> >>>> long strLength(const char *s)
> >>>> {
> >>>> =A0 =A0long len =3D 0;
> >>>> =A0 =A0while(*s++) ++len;
> >>>> =A0 =A0return len;
> >>>> }
> >>> An unnecessary increment on every loop. Potentially expensive for lon=
g
> >>> blocks. Nilges might be faster in many cases.
> >> Whoa, missed that.
> > You also missed my advice (upthread) to ditch the function completely
> > and use the standard library, which will wipe the floor with both versi=
ons.
>
> Typically, yes.
>
> That said, I do like the idiom
> =A0 =A0 =A0 =A0 size_t lenstr(char *string) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 char *end =3D string;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 while (*end++)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return end - string;
> =A0 =A0 =A0 =A0 }
>
Doesn't even compile on a "standard" compiler that doesn't support
initialization in decaration.

Contains a major bug. end is postincremented when *end =3D=3D NUL,
therefore your code gives and off by one answer. This is obvious.

Confirming this on the Microsoft compiler in STANDARD C mode:

char *string;
char *end;
string =3D "123";
end =3D string;
while(*end++);
printf("%d\n", end - string);

This prints 4.

How DARE you. How DARE you attack Schildt et al. for bugs as if you
never made stupid mistakes? How DARE you call people "trolls" and
"morons" for making less serious mistakes?

Does your incompetence, hypocrisy and narcissism know no upper bound?

> Not that it's likely to make a noticeable difference. =A0Or that it's lik=
ely
> worth it when obviously the standard library one will be fine.
>
> -s
> --
> Copyright 2010, all wrongs reversed. =A0Peter Seebach / usenet-nos...@see=
bs.nethttp://www.seebs.net/log/<-- lawsuits, religion, and funny picturesht=
tp://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
```
 0
spinoza1111 (3246)
2/14/2010 6:01:03 AM
```On Feb 14, 4:09=A0am, Keith Thompson <ks...@mib.org> wrote:
> Seebs <usenet-nos...@seebs.net> writes:
>
> [...]
>
> > That said, I do like the idiom
> > =A0 =A0size_t lenstr(char *string) {
> > =A0 =A0 =A0 =A0 =A0 =A0char *end =3D string;
> > =A0 =A0 =A0 =A0 =A0 =A0while (*end++)
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0;
> > =A0 =A0 =A0 =A0 =A0 =A0return end - string;
> > =A0 =A0}
>
> > Not that it's likely to make a noticeable difference. =A0Or that it's l=
ikely
> > worth it when obviously the standard library one will be fine.
>
> Note that ``end - string'' yields a value of type ptrdiff_t, a signed
> type which very likely can't represent all values of type size_t.
>
> This is unlikely to be an issue in practice. =A0On typical 32-bit
> systems, problems show up only for strings longer than 2 gigabytes,
> and even then the properties of 2's-complement arithmetic are likely
> to result in the correct answer anyway.
>
> But all this analysis, resulting in the conclusion that it will
> almost certainly work properly, becomes unnecessary if you just
> use strlen().
>
> --
> Keith Thompson (The_Other_Keith) ks...@mib.org =A0<http://www.ghoti.net/~=
kst>
> Nokia
> "We must do something. =A0This is something. =A0Therefore, we must do thi=
s."
> =A0 =A0 -- Antony Jay and Jonathan Lynn, "Yes Minister"

Kenny McCormack, thou should'st be here at this hour:
For Kiki is in finest Form, posting pompously and sour:
Exhibiting ersatz Learning, and utter Pedantry:
He concludes, after "all this analysis" that "almost certainly"
That "it" (Seebie's shit) will yeah right..."work properly".
But for "123" Seebie's code grinds out to the amazement of the Crowd
The number...the number...FOUR, to dismay that is loud.
Whilst we the putative Trolls do dance amidst burning Tyres
Laughing our hairy Asses off at the doom of Pedantry's pretentious
spires!
```
 0
spinoza1111 (3246)
2/14/2010 6:07:29 AM
```On Feb 14, 7:03=A0am, Phil Carmody <thefatphil_demun...@yahoo.co.uk>
wrote:
> Seebs <usenet-nos...@seebs.net> writes:
> > On 2010-02-13, Richard Heathfield <r...@see.sig.invalid> wrote:
> >>spinoza1111wrote:
> >>> On Feb 13, 8:18 pm, Richard <rgrd...@gmail.com> wrote:
> >>>> Richard Heathfield <r...@see.sig.invalid> writes:
> >>>>> long strLength(const char *s)
> >>>>> {
> >>>>> =A0 =A0long len =3D 0;
> >>>>> =A0 =A0while(*s++) ++len;
> >>>>> =A0 =A0return len;
> >>>>> }
> >>>> An unnecessary increment on every loop. Potentially expensive for lo=
ng
> >>>> blocks. Nilges might be faster in many cases.
>
> >>> Whoa, missed that.
>
> >> You also missed my advice (upthread) to ditch the function completely
> >> and use the standard library, which will wipe the floor with both vers=
ions.
>
> > Typically, yes.
>
> > That said, I do like the idiom
> > =A0 =A0size_t lenstr(char *string) {
> > =A0 =A0 =A0 =A0 =A0 =A0char *end =3D string;
> > =A0 =A0 =A0 =A0 =A0 =A0while (*end++)
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0;
> > =A0 =A0 =A0 =A0 =A0 =A0return end - string;
> > =A0 =A0}
>
> > Not that it's likely to make a noticeable difference. =A0Or that it's l=
ikely
> > worth it when obviously the standard library one will be fine.
>
> You ran straight into the fencepost. And can we have more const,

He sure did. I was hoping as I went chronologically through the thread
to find someone who could find the bug before I woke up here in Asia,
but I posted my own correction before looking at replies to Seebie. It
looks like you may have, but you should have had the cojones to
describe the bug, taking the risk like a man that you may misdescribe
the bug. It's called Habermas' communicative reason and a common
search for TRUTH.
>
> Phil, who uses strlen().

Sensible chap.

Ed, who uses C Sharp.

> --
> Any true emperor never needs to wear clothes. -- Devany on r.a.s.f1

```
 0
spinoza1111 (3246)
2/14/2010 6:10:53 AM
```On Feb 14, 7:05=A0am, c...@tiac.net (Richard Harter) wrote:
> On Sat, 13 Feb 2010 01:25:27 -0800 (PST),spinoza1111
>
> <spinoza1...@yahoo.com> wrote:
> >On Feb 13, 2:46=3DA0am,spinoza1111<spinoza1...@yahoo.com> wrote:
> >...code...
>
> >I noticed that in the latest (13 Feb) version of the code, with the
> >fix to the one-character replace found by Ben B, there were some file
> >nits: two long lines split and blanks at end of continued macro lines.
>
> >Let's see if I can get rid of these problems.
>
> >Also, I misspoke. The failure to handle Ben's example was caused by an
> >earlier change.
>
> >Here is the latest code, without the console output.
>
> I have no particular interest in this programming challenge,
> though I do find some of the commentary amusing. =A0I thought it
> might be of interest to do a code review. =A0The following is not
> an endorsement or a condemnation of the code. =A0Rather it is an
> informal account of code features that are problematic.
>
> Notes on the Nilges code:
>
> (1) At no point is there a comprehensive specification. =A0A fair
> number of corner cases are left up in the air. =A0These include
> overlapping targets, and empty targets. =A0There is no statement
> of error handling strategy. =A0
>
> (2) There are instances of failure to protect against
> dereferencing null pointers. =A0Thus in function strLength the for
> loop will dereference a null pointer if argument strInstring is
> a null pointer. =A0Similarly function replace checks strTarget but
> not strMaster. =A0ptrIndex1 is initialized to strMaster. =A0The
> while loop, while(*ptrIndex1), will dereference a null pointer
> if strMaster is null. =A0
>
> The test cases do not check for null arguments nor all instances
> of empty strings. =A0
>
> (3) The TESTER macro is cumbersome and should be replaced by a
> function. =A0
>
> (4) It would be better if the test cases were moved to a
> separate file - the plan would be for the main function to read
> the test cases from from the test cases file and then compare
> the actual test results with the expected test results. =A0
>
> more like coding notes written on the spur of the moment to
> remind the coder about what was going on. =A0There is no statement
> of the algorithm being used; the comments often reference
> concepts that are not explained. =A0For example, there is no
> precise definition of segment nor of handle. =A0
>
> (6) The commenting format is not well chosen. =A0The comments
> break into the code and vice versa. =A0
>
> (7) The code author uses a bizarre, idiosyncratic, and long
> winded variant of Hungarian notation. =A0It's his privilege. =A0
> Unfortunately the long names used are not informative. =A0For
> example, the ptrIndex* variables. =A0What on earth are they, and
> what are their invariants? =A0The only way to know what they are
> is play computer, walk through the code, and reconstruct what
> the coder's intent was. =A0
>
> Then there are the ptrSegmentStruct variables. =A0One has a suffix
> of Starts, one of Prev, and one is without a suffix. =A0Since the
> key idea of the implementation is to generate a linked list of
> segments, each (except possibly the last) being terminated by
> the target string, it turns out that the ptrSegmentStructStarts
> refers to the list head, ptrSegmentStruct refers to the current
> pointer into the list, and ptrSegmentStructPrev refers to the
> previous pointer into the list. =A0Or perhaps not. =A0
>
> (8) The scheme of allocating space for each segment is mildly
> inefficient, but is much better than reallocing space for the
> output string. =A0In any case it is doubtful that execution
> efficiency is among the objectives of this exercise. =A0
>
> (9) In some places the code is overly complex. =A0A case in point
> is:
>
> lngNewLength +=3D ptrSegmentStruct->lngSegmentLength +
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (ptrIndex2 && !*ptrIndex2
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0?
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0lngReplacementLength
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0:
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A00);
>
> There are several other instances of unnecessary complexity. =A0
> The updating of the never defined Index variables is a case in
> point. =A0
>
> (10) Only one of strNew, strNewStart is needed.
>
> (11) In conclusion, it is difficult to determine whether the
> code works correctly because the design is not spelled out, the
> variables are not properly documention, the testing framework is
> inadequate, and the baroque nomeclature and coding complicate
> analysis. =A0
>
> Richard Harter, c...@tiac.nethttp://home.tiac.net/~cri,http://www.varinom=
a.com
> Infinity is one of those things that keep philosophers busy when they
> could be more profitably spending their time weeding their garden.

Looks great, and it looks like I need to review this carefully. I am
in my morning "pass" through many responses, including responses to
```
 0
spinoza1111 (3246)
2/14/2010 6:12:29 AM
```On Feb 14, 7:23=A0am, "Chris M. Thomasson" <n...@spam.invalid> wrote:
> "Seebs" <usenet-nos...@seebs.net> wrote in message
>
> news:slrnhndrhg.3ec.usenet-nospam@guild.seebs.net...
>
> [...]
>
> > That said, I do like the idiom
> > size_t lenstr(char *string) {
> > char *end =3D string;
> > while (*end++)
> > ;
> > return end - string;
> > }
>
> > Not that it's likely to make a noticeable difference. =A0Or that it's l=
ikely
> > worth it when obviously the standard library one will be fine.
>
> I believe that you have a bug in that code Seebs. Perhaps you meant
> _____________________________________________________
> size_t
> xstrlen(char const* string)
> {
> =A0 =A0 char const* end =3D string;
> =A0 =A0 while (*end) ++end;
> =A0 =A0 return end - string;}
>
> _____________________________________________________
>
> ?

Good call, Chris.
```
 0
spinoza1111 (3246)
2/14/2010 6:13:04 AM
```On Feb 14, 7:35=A0am, Seebs <usenet-nos...@seebs.net> wrote:
> On 2010-02-13, Chris M. Thomasson <n...@spam.invalid> wrote:
>
> > I believe that you have a bug in that code Seebs.
>
> Extremely likely.
>
> This is one of the reasons I rely on the standard library -- my success r=
ate
> in avoiding fencepost errors is slightly *less* than chance. =A0I'm not a=
ctually
> very good at this stuff, which is why I spend so much time thinking about=
how
> to do it better.

No argument there, none whatsoever. But lemme ask you a question.
Where the fuck do you get off criticising people who are, if not
perfect, better than you? People like Schildt?

And why do suppose I started posting my own (vastly more challenging)
solution early when I knew it might have bugs, being self-confident
enough to risk exposure?

It's because REAL programming, as opposed to some bureaucratic job
finding other people's bugs, is humbling and challenging, and REAL
code review happens outside the language game of capitalism.

Read Habermas. And get a clue.
>
> -s
> --
> Copyright 2010, all wrongs reversed. =A0Peter Seebach / usenet-nos...@see=
bs.nethttp://www.seebs.net/log/<-- lawsuits, religion, and funny picturesht=
tp://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!

```
 0
spinoza1111 (3246)
2/14/2010 6:17:10 AM
```On Feb 14, 9:10=A0am, "bartc" <ba...@freeuk.com> wrote:
> "Seebs" <usenet-nos...@seebs.net> wrote in message
>
> news:slrnhn628c.o3u.usenet-nospam@guild.seebs.net...
>
>
>
>
>
> > This may have gotten buried given that it started in a Nilges thread,
> > but it's actually pretty interesting.
>
> > There was some discussion of algorithms to perform the task:
> > Inputs: =A0target string, replacement string, original string
> > Output: =A0a newly-allocated string containing the original
> > =A0 string with each copy of the target string replaced with the
> > =A0 replacement string.
>
> > Here's a hunk of mine:
>
> > =A0 =A0 =A0 =A0for (count =3D 0, t =3D strstr(target, in); t && *t; t =
=3D strstr(t, in))
> > {
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0++count;
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0t +=3D inlen;
> > =A0 =A0 =A0 =A0}
>
> > Here's a hunk of another one:
>
> >> =A0 =A0 ptrIndex1 =3D strMaster;
> >> =A0 =A0 while(*ptrIndex1)
>
> > These hunks are essentially performing the same part of the core loop;
> > find the next occurrence of the target string in the original string.
>
> I've looked at both. The first is easier on the eye, but I still can't
> figure out what it does. You say, it finds the *next* occurence of the
> target, why a loop then?
>
> > The second one was written by Edward Nilges ("spinoza1111"). =A0He offe=
rs
> > in its defense the assertion that it's the "best" algorithm. =A0(Neverm=
ind
> > that it's got a bug; the bug could be fixed easily.)
>
> You can't really compare these (assuming they really do do the same thing=
);
> your code uses some presumably tried and tested library function (strstr)=
to
> do the tricky part, so you're comparing a *call* to that function to an
> experimental *implementation* of it. That doesn't sound fair..

English public school rules apply to this fight, Bart: cf. Flashman's
savaging of Tom Brown in Tom Brown's Schooldays. Which is why it's so
much fun to win, as I am winning, despite Seebie's Flashman-like
behavior. He can't get a simple strlen replace right, yet dares to
attack my much more sophisticated and challenging solution and
Schildt.

I would prefer a Habermasian-civil structured walkthrough. However, we
live in a barbaric capitalism in which there are no holds barred. It's
Extreme Fighting. But:

Hasta la victoria siempre! - Ernesto Che Guevara

En afrenta y oprobio sumido,
=A1A las armas, valientes, corred! - La Bayamesa
>
> > it is, before trying to optimize. =A0You may, or may not, be able to
> > outperform
> > a given library's implementation of strstr().
>
> The efficiency varies. On my lccwin32 and DMC compilers, the time to find=
an
> "A" string, in a string consisting entirely of As, seems to depend on the
> length of the string it's searching (perhaps it's doing a strlen() first?=
).
> On gcc it's instant.
>
> (I came across the problem in a related function strchr(), in Malcolm's
> Minibasic program, where it had the effect, on large input files, of slow=
ing
> down the interpreter from 80K lines per second to about 2K. Replacing the
> strchr() call with one line of custom code (I think it was just looking f=
or
> next EOL), fixed that.)

Sounds like you have real applied comp sci chops.

>
> --
> Bartc
```
 0
spinoza1111 (3246)
2/14/2010 6:27:07 AM
```On Feb 14, 9:40=A0am, Joe Wright <joewwri...@comcast.net> wrote:
> Seebs wrote:
> > On 2010-02-13, Chris M. Thomasson <n...@spam.invalid> wrote:
> >> I believe that you have a bug in that code Seebs.
>
> > Extremely likely.
>
> > This is one of the reasons I rely on the standard library -- my success=
rate
> > in avoiding fencepost errors is slightly *less* than chance. =A0I'm not=
actually
> > very good at this stuff, which is why I spend so much time thinking abo=
ut how
> > to do it better.
>
> > -s
>
> The humility is a good touch. You can use mine.

No, it is not. It is the humility of Dickens' Uriah Heep, for it is an
"humility" unlinked to the charitable willingness to REFRAIN from
posting unwarranted attacks on Schildt and others, an "humility"
targets.

Dijkstra's essay "The Humble Programmer" was in my direct experience
misused. It was transformed into a call on programmers to be
subservient to corporate authority right at the end of the Sixties,
when the authority of property was in question world-wide. But
Dijkstra meant nothing of the sort.

>
> size_t Strlen(char *s)
> {
> =A0 =A0 size_t l =3D 0;
> =A0 =A0 if (s) while (*s++) l++;
> =A0 =A0 return l;
>
> }
>
> --
> Joe Wright
> "If you rob Peter to pay Paul you can depend on the support of Paul."

```
 0
spinoza1111 (3246)
2/14/2010 6:31:57 AM
```On Feb 14, 10:02=A0am, Seebs <usenet-nos...@seebs.net> wrote:
> On 2010-02-14, bartc <ba...@freeuk.com> wrote:
>
> > I've looked at both. The first is easier on the eye, but I still can't
> > figure out what it does. You say, it finds the *next* occurence of the
> > target, why a loop then?
>
> Because it finds the next occurrence repeatedly until there's no more.
>
> > You can't really compare these (assuming they really do do the same thi=
ng);
> > your code uses some presumably tried and tested library function (strst=
r) to
> > do the tricky part, so you're comparing a *call* to that function to an
> > experimental *implementation* of it. That doesn't sound fair..
>
> I think it's extremely fair, because it highlights the flaw in his "I
> refuse to use the library functions" attitude.

This is a false caricature. Were I to use C, I'd use what library
functions were safe. But I would create my own string library.

However, the corporate language game is to transform responsible adult
thought into a childish "attitude".

So, I have a Bad Attitude. I actually want to do a good job. Quite
frankly, based on my thirty years I don't think you do, in a
standalone, independent sense, anything like a good job in your chosen
profession, but this doesn't matter. Managers design organizations so
that errors are hopefully factored out, and in the social machine so
created, a person who can by himself do a complete good job is in fact
a "square peg in a round hole".

However, this reality is concealed from today's programmers, owing to
the fact that capitalism is a basically inhuman system despite its
good parts. People want to be *homo faber*, man the toolmaker, and
they don't want to do a small piece of a job only to see their work
corrected and criticised by people who can't themselves do the same
work.

Therefore a Pop culture pervades in programming shops: the delusion
that each male member (where the shop must usually exclude women in
order for the illusion to work) is "rilly" a proud and independent
professional when in fact he's the type of programmer who can't get a
strlen right, finds well-formatted code "unreadable" simply by virtue
of the pains taken by the formatter, the merest thought of which makes
our boy's butt hurt in that it's a reminder of a lost humanity, and
who finds correct grammar of complexity > low n "verbose".

>
> Agreed that there are cases where there's reasons not to do that.

"There are", not "there's", Grammar Guy.
>
> -s
> --
> Copyright 2010, all wrongs reversed. =A0Peter Seebach / usenet-nos...@see=
bs.nethttp://www.seebs.net/log/<-- lawsuits, religion, and funny picturesht=
tp://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!

```
 0
spinoza1111 (3246)
2/14/2010 6:42:21 AM
```OK, I implemented and tested (in about 25 minutes if you want to know)
the above-described solution to the "showstopper performance bug" that
Seebach more or less found.

This was the creation of many zero-length TYPsegmentstruct occurrences
when there are multiple adjacent hits. This code implements the plan
above.

The same cautions (make sure your browser doesn't split two lines, the
TESTER header and the final printf, at position 67 or whatever: make
sure it doesn't add a blank to the end of the TESTER macro
continuation lines) apply.

As before, a complete regression test is included.

"Oh yes. In Europe a much larger fraction of the population can write.
People in America have really suffered from the combination of TV,
which makes reading superfluous, and the telephone. A few years ago I
was at CalTech and that is a hiqh quality place and everybody
recommends it because the students are so bright. A graduate confessed
to me=97no he did not confess, he just stated it, that he did not care
about his writing, since he was preparing himself for an industrial
career. Poor industry!" - Edsger Dijkstra, 1985

"You talk like a fag, and you're shit's all fucked up." - Idiocracy,
Mike Judge, 2005

// ***************************************************************
// *                                                             *
// * replace() demo                                              *
// *                                                             *
// * Demonstrates how to replace non-NUL-defined strings in C    *
// * using a simple function, and bypassing string.h.            *
// *                                                             *
// * C H A N G E   R E C O R D --------------------------------- *
// *   DATE     PROGRAMMER     DESCRIPTION OF CHANGE             *
// * --------   ----------     --------------------------------- *
// * 02 07 10   Nilges         Version 1.0                       *
// *                                                             *
// * 02 07 10   Nilges         Bug: partial matches not handled  *
// *                           correctly: need to iterate search *
// *                           for match.                        *
// *                                                             *
// * 02 07 10   Nilges         1.  Santosh suggested tests       *
// *                           2.  Heathfield put the boot in re *
// *                               including malloc              *
// *                                                             *
// * 02 07 10   Nilges         1.  Remove string.h use and code  *
// *                               strlen by hand                *
// *                               inline.                       *
// *                           3.  free() storage                *
// *                           4.  Use macro for testing         *
// *                           5.  Bug: calculation of           *
// *                               lngNewLength used incorrect   *
// *                               index (intIndex3 instead of 2)*
// *                               which caused a memory leak.   *
// *                                                             *
// * 02 07 10   Nilges         1.  Bug: Ike Naar test failed.    *
// *                               At end of scan loop, main     *
// *                               string pointer was not        *
// *                               correctly updated from index3 *
// *                                                             *
// * 02 07 10   Nilges         Added new Santosh test            *
// *                                                             *
// * 02 07 10   Nilges         Added new Ike Naar test           *
// *                                                             *
// * 02 08 10   Nilges         1.  Added some new comments       *
// *                           2.  Make "check for a complete    *
// *                               match "structured" by means   *
// *                               of a tested assignment        *
// *                           3.  Get rid of "replace at end"   *
// *                               evilness: the only time this  *
// *                               flag is meaningful is in the  *
// *                               LAST segment.                 *
// *                           4.  Return replace count          *
// *                           5.  TESTER macro assertion added  *
// *                                                             *
// * 02 10 10   Nilges         1.  Bug fix: in a partial match,  *
// *                               the main scan index is set to *
// *                               one past the end, which misses*
// *                               full matches that start       *
// *                               between the first character of*
// *                               the partial match and its end.*
// *                                                             *
// *                               No longer updating the main   *
// *                               scan index (ptrIndex1) to the *
// *                               point of partial match        *
// *                               failure: setting it one past  *
// *                               the first character of the    *
// *                               partial match.                *
// *                                                             *
// *                           2.  Line up expected & actual     *
// *                               results per excellent         *
// *                               suggestion (who made this?)   *
// *                                                             *
// *                           3.  After a partial match, update *
// *                               the main handle search index  *
// *                               (ptrIndex1) to the first      *
// *                               occurrence of the handle      *
// *                               character after the start of  *
// *                               the partial match, or to the  *
// *                               index of the unmatched char.  *
// *                                                             *
// * 021310     Nilges         Bug: failed to handle a one-char  *
// *                           replace (of a by x in b) since    *
// *                           we set ptrIndex2 to point to NUL  *
// *                           which made it appear that there   *
// *                           was a match. When the main index  *
// *                           to the master string (ptrIndex1)  *
// *                           goes off the end of a cliff, we   *
// *                           needed to break out of the search *
// *                           loop.                             *
// *                                                             *
// *                           This also entailed setting the    *
// *                           target index ptrIndex2 to 0 at the*
// *                           beginning of each search so that  *
// *                           it is not erroneously used to     *
// *                           indicate that there's an insert   *
// *                           needed at the end.                *
// *                                                             *
// *                           to verify that the code works     *
// *                           when the string and target end    *
// *                           at the same time.                 *
// *                                                             *
// * 02 14 10   Nilges         This version detects zero length  *
// *                           segments and merges them          *
// * ----------------------------------------------------------- *
// *                                                             *
// * "In the near future we shall have to live with the          *
// *  superstition that programming is 'so easy that even a      *
// *  Republican can do it!'"                                    *
// *                                                             *
// *                   - E. W. Dijkstra                          *
// *                                                             *
// *                                                             *
// ***************************************************************
#include <stdio.h>
#include <stdlib.h>

// ***** Segmentation *****
struct TYPsegmentstruct
{ char * strSegment;
long lngSegmentLength;
struct TYPsegmentstruct * ptrNext; };

// ---------------------------------------------------------------
// Calculate string length
//
//
long strLength(char *strInstring)
{
char *ptrInstring;
for (ptrInstring =3D strInstring; *ptrInstring; ptrInstring++);
return ptrInstring - strInstring;
}

// ---------------------------------------------------------------
// Replace target by replacement string in master string
//
//
// Caution: the string returned by this function should be freed.
//
//
char * replace(char * strMaster,
char * strTarget,
char * strReplacement,
long * ptrReplacements)
{
char * ptrIndex0;
char * ptrIndex1;
char * ptrIndex2;
char * ptrIndex3;
char * ptrIndex4;
char * strNew;
char * strNewStart;
long lngNewLength;
long lngCount;
long lngReplacementLength;
struct TYPsegmentstruct * ptrSegmentStructStarts;
struct TYPsegmentstruct * ptrSegmentStruct;
struct TYPsegmentstruct * ptrSegmentStructPrev;
lngReplacementLength =3D strLength(strReplacement);
if (!*strTarget)
{
printf("Error in calling replace(): target can't be null");
abort();
}
ptrIndex1 =3D strMaster;
ptrSegmentStruct =3D 0;
ptrSegmentStructPrev =3D 0;
lngNewLength =3D 0;
*ptrReplacements =3D 0;
while(*ptrIndex1)
{
ptrIndex0 =3D ptrIndex1;
ptrIndex2 =3D 0;
while (-1)
{
// --- Check for (one character) handle
for(;
*ptrIndex1 && *ptrIndex1 !=3D *strTarget;
ptrIndex1++);
if (!*ptrIndex1) break;
// --- Check for complete match while remembering the
// --- last position of the handle
ptrIndex4 =3D 0;
for(ptrIndex2 =3D strTarget + 1,
ptrIndex3 =3D ptrIndex1 + 1;
*ptrIndex3
&&
*ptrIndex2
&&
*ptrIndex3 =3D=3D *ptrIndex2;
ptrIndex3++, ptrIndex2++)
{
if (*ptrIndex3 =3D=3D *strTarget
&&
ptrIndex4 =3D=3D 0) ptrIndex4 =3D ptrIndex3;
}
// End test: check complete match, update main ptr past
// partial match while checking for end of loop
if ((!*ptrIndex2 ? ((*ptrReplacements)++, -1) : 0)
||
(!*ptrIndex3 ? (ptrIndex1 =3D ptrIndex3, -1) : 0))
break;
// Update the main search pointer
ptrIndex1 =3D (ptrIndex4 =3D=3D 0 ? ptrIndex3 : ptrIndex4);
}
// --- Create new segment
if (ptrSegmentStruct !=3D 0
&&
ptrSegmentStruct->lngSegmentLength <=3D 0
&&
ptrIndex1 =3D=3D ptrIndex0)
{
// We don't want to create a lot of null segments
ptrSegmentStruct->lngSegmentLength--;
}
else
{
if (!(ptrSegmentStruct =3D
malloc(sizeof(struct TYPsegmentstruct))))
abort();
ptrSegmentStruct->strSegment =3D ptrIndex0;
ptrSegmentStruct->lngSegmentLength =3D
ptrIndex1 - ptrIndex0;
ptrSegmentStruct->ptrNext =3D 0;
if (ptrSegmentStructPrev !=3D 0)
ptrSegmentStructPrev->ptrNext =3D ptrSegmentStruct;
else
ptrSegmentStructStarts =3D ptrSegmentStruct;
ptrSegmentStructPrev =3D ptrSegmentStruct;
}
// --- Update mallocation length
lngNewLength +=3D (ptrSegmentStruct->lngSegmentLength <=3D 0
?
0
:
ptrSegmentStruct->lngSegmentLength)
+
(ptrIndex2 && !*ptrIndex2
?
lngReplacementLength
:
0);
// --- Get past end of target string & iterate
if (*ptrIndex1) ptrIndex1 =3D ptrIndex3;
}
// --- Allocate just enough storage for the new string
if (!(strNewStart =3D malloc(lngNewLength + 1))) abort();
// --- Build the new string whilst freeing the list
strNew =3D strNewStart;
ptrSegmentStruct =3D ptrSegmentStructStarts;
while (ptrSegmentStruct)
{
for (ptrIndex1 =3D ptrSegmentStruct->strSegment,
lngCount =3D 0;
lngCount < ptrSegmentStruct->lngSegmentLength;
ptrIndex1++, lngCount++, strNew++)
*strNew =3D *ptrIndex1;
if (ptrSegmentStruct->ptrNext
||
ptrIndex2 !=3D 0 && !*ptrIndex2)
for (lngCount =3D
(ptrSegmentStruct->lngSegmentLength
>
0
?
1
:
-(ptrSegmentStruct->lngSegmentLength) + 1);
lngCount > 0;
lngCount--)
for (ptrIndex1 =3D strReplacement;
*ptrIndex1;
ptrIndex1++, ++strNew)
*strNew =3D *ptrIndex1;
ptrSegmentStructPrev =3D ptrSegmentStruct;
ptrSegmentStruct =3D ptrSegmentStruct->ptrNext;
free(ptrSegmentStructPrev);
}
*strNew =3D '\0';
return strNewStart;
}

// ---------------------------------------------------------------
// Statement-format test macro
//
//
#define TESTER(resultPtr, master, target, replacement, expected,
expectedReplacements, replacements) \
{ \
printf("Replace \"%s\" by \"%s\" in \"%s\"\n", \
(target), (replacement), (master)); \
printf("Expect \"%s\":\n       \"%s\"\n", \
(expected), \
resultPtr =3D replace((master), \
(target), \
(replacement), \
&(replacements))); \
printf("Replacements expected: %d: replacements: %d\n", \
(expectedReplacements), \
(replacements)); \
if (!(strLength(resultPtr) \
=3D=3D \
strLength(master) \
+ \
(strLength(replacement)-strLength(target)) \
* \
replacements)) \
printf("Assertion failed\n"); \
printf("\n\n"); \
free(resultPtr); \
}

// ---------------------------------------------------------------
// Main procedure
//
//
int main()
{
char *ptrResult;
long lngReplacements;
printf("\nReplace\n\n\n");
TESTER(ptrResult,
"xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"x",
"y",
"yyyyyyyyyyyyyyyyyyyyyyyyyyyy",
28,
lngReplacements)
TESTER(ptrResult,
"1111123bbb1111123bbb11123bb11111231111112111111123",
"111123",
"ono",
"1onobbb1onobbb11123bb1ono1111112111ono",
4,
lngReplacements)
TESTER(ptrResult,
"bbb1111123bbbbb",
"111123",
"ono",
"bbb1onobbbbb",
1,
lngReplacements)
TESTER(ptrResult,
"a stupid error",
"stupid error",
"miracle",
"a miracle",
1,
lngReplacements)
TESTER(ptrResult,
"a stupid error",
"stupid",
"miracle",
"a miracle error",
1,
lngReplacements)
TESTER(ptrResult,
"the stupid error",
"the stupid error",
"a miracle",
"a miracle",
1,
lngReplacements)
TESTER(ptrResult,
"the miracle",
"the",
"a",
"a miracle",
1,
lngReplacements)
TESTER(ptrResult,
"a miraclsnirpKamunkle",
"snirpKamunkle",
"e",
"a miracle",
1,
lngReplacements)
TESTER(ptrResult,
"a miraclesnirpKamunkle",
"a miracle",
"",
"snirpKamunkle",
1,
lngReplacements)
TESTER(ptrResult,
" a miraclesnirpKamunkle",
"a miracle",
"",
" snirpKamunkle",
1,
lngReplacements)
TESTER(ptrResult,
" a miraclesnirpKamunklea miraclea miracle",
"a miracle",
"",
" snirpKamunkle",
3,
lngReplacements)
TESTER(ptrResult,
"a miracle a miraclesnirpKamunkle a Miraclea
miracleamiracle",
"a miracle",
"",
" snirpKamunkle a Miracle",
3,
lngReplacements)
TESTER(ptrResult,
"a stupid errord",
"stupid error",
"miracle",
"a miracled",
1,
lngReplacements)
TESTER(ptrResult,
"a stupid errod",
"stupid error",
"miracle",
"a stupid errod",
0,
lngReplacements)
TESTER(ptrResult,
"a sstupid error",
"stupid error",
"miracle",
"a smiracle",
1,
lngReplacements)
TESTER(ptrResult,
"a stupid errorstupid error",
"stupid error",
"miracle",
"a miraclemiracle",
2,
lngReplacements)
TESTER(ptrResult,
"a stupid error stupiderror",
"stupid error",
"miracle",
"a miracle stupiderror",
1,
lngReplacements)
TESTER(ptrResult,
"bbbbbbbbbb",
"b",
"a",
"aaaaaaaaaa",
10,
lngReplacements)
TESTER(ptrResult,
"In the halls of R'yleh great %s lies dreaming",
"%s",
"Cthulu",
"In the halls of R'yleh great Cthulu lies dreaming",
1,
lngReplacements)
TESTER(ptrResult,
"%s%s%s%s%s%s",
"%s",
"Cthulu",
"CthuluCthuluCthuluCthuluCthuluCthulu",
6,
lngReplacements)
TESTER(ptrResult,
"banana",
"ana",
"oat",
"boatna",
1,
lngReplacements)
TESTER(ptrResult,
" a stupid errorstupid errorHeystupid errors",
"stupid error",
"+",
" a ++Hey+s",
3,
lngReplacements)
TESTER(ptrResult,
"foo barfoo barf",
"foo bar",
"bas",
"basbasf",
2,
lngReplacements)
TESTER(ptrResult,
"abab",
"ba",
"ba",
"abab",
1,
lngReplacements)
TESTER(ptrResult,
"abab",
"bab",
"boop",
"aboop",
1,
lngReplacements)
TESTER(ptrResult,
"banana",
"ana",
"ono",
"bonona",
1,
lngReplacements)
TESTER(ptrResult,
"a",
"x",
"b",
"a",
0,
lngReplacements)
TESTER(ptrResult,
"x",
"x",
"b",
"b",
1,
lngReplacements)
TESTER(ptrResult,
"egregious",
"egregious",
"egregious",
"egregious",
1,
lngReplacements)
TESTER(ptrResult,
"egregious",
"egregious",
"x",
"x",
1,
lngReplacements)
printf("\n\nTesting complete: check output carefully: \"Assertion
failed\" should not occur!\n\n");
return 0;
}

Replace

Replace "x" by "y" in "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Expect "yyyyyyyyyyyyyyyyyyyyyyyyyyyy":
"yyyyyyyyyyyyyyyyyyyyyyyyyyyy"
Replacements expected: 28: replacements: 28

Replace "111123" by "ono" in
"1111123bbb1111123bbb11123bb11111231111112111111123"
Expect "1onobbb1onobbb11123bb1ono1111112111ono":
"1onobbb1onobbb11123bb1ono1111112111ono"
Replacements expected: 4: replacements: 4

Replace "111123" by "ono" in "bbb1111123bbbbb"
Expect "bbb1onobbbbb":
"bbb1onobbbbb"
Replacements expected: 1: replacements: 1

Replace "stupid error" by "miracle" in "a stupid error"
Expect "a miracle":
"a miracle"
Replacements expected: 1: replacements: 1

Replace "stupid" by "miracle" in "a stupid error"
Expect "a miracle error":
"a miracle error"
Replacements expected: 1: replacements: 1

Replace "the stupid error" by "a miracle" in "the stupid error"
Expect "a miracle":
"a miracle"
Replacements expected: 1: replacements: 1

Replace "the" by "a" in "the miracle"
Expect "a miracle":
"a miracle"
Replacements expected: 1: replacements: 1

Replace "snirpKamunkle" by "e" in "a miraclsnirpKamunkle"
Expect "a miracle":
"a miracle"
Replacements expected: 1: replacements: 1

Replace "a miracle" by "" in "a miraclesnirpKamunkle"
Expect "snirpKamunkle":
"snirpKamunkle"
Replacements expected: 1: replacements: 1

Replace "a miracle" by "" in " a miraclesnirpKamunkle"
Expect " snirpKamunkle":
" snirpKamunkle"
Replacements expected: 1: replacements: 1

Replace "a miracle" by "" in " a miraclesnirpKamunklea miraclea
miracle"
Expect " snirpKamunkle":
" snirpKamunkle"
Replacements expected: 3: replacements: 3

Replace "a miracle" by "" in "a miracle a miraclesnirpKamunkle a
Miraclea miracleamiracle"
Expect " snirpKamunkle a Miracle":
" snirpKamunkle a Miracleamiracle"
Replacements expected: 3: replacements: 3

Replace "stupid error" by "miracle" in "a stupid errord"
Expect "a miracled":
"a miracled"
Replacements expected: 1: replacements: 1

Replace "stupid error" by "miracle" in "a stupid errod"
Expect "a stupid errod":
"a stupid errod"
Replacements expected: 0: replacements: 0

Replace "stupid error" by "miracle" in "a sstupid error"
Expect "a smiracle":
"a smiracle"
Replacements expected: 1: replacements: 1

Replace "stupid error" by "miracle" in "a stupid errorstupid error"
Expect "a miraclemiracle":
"a miraclemiracle"
Replacements expected: 2: replacements: 2

Replace "stupid error" by "miracle" in "a stupid error stupiderror"
Expect "a miracle stupiderror":
"a miracle stupiderror"
Replacements expected: 1: replacements: 1

Replace "b" by "a" in "bbbbbbbbbb"
Expect "aaaaaaaaaa":
"aaaaaaaaaa"
Replacements expected: 10: replacements: 10

Replace "%s" by "Cthulu" in "In the halls of R'yleh great %s lies
dreaming"
Expect "In the halls of R'yleh great Cthulu lies dreaming":
"In the halls of R'yleh great Cthulu lies dreaming"
Replacements expected: 1: replacements: 1

Replace "%s" by "Cthulu" in "%s%s%s%s%s%s"
Expect "CthuluCthuluCthuluCthuluCthuluCthulu":
"CthuluCthuluCthuluCthuluCthuluCthulu"
Replacements expected: 6: replacements: 6

Replace "ana" by "oat" in "banana"
Expect "boatna":
"boatna"
Replacements expected: 1: replacements: 1

Replace "stupid error" by "+" in " a stupid errorstupid errorHeystupid
errors"
Expect " a ++Hey+s":
" a ++Hey+s"
Replacements expected: 3: replacements: 3

Replace "foo bar" by "bas" in "foo barfoo barf"
Expect "basbasf":
"basbasf"
Replacements expected: 2: replacements: 2

Replace "ba" by "ba" in "abab"
Expect "abab":
"abab"
Replacements expected: 1: replacements: 1

Replace "bab" by "boop" in "abab"
Expect "aboop":
"aboop"
Replacements expected: 1: replacements: 1

Replace "ana" by "ono" in "banana"
Expect "bonona":
"bonona"
Replacements expected: 1: replacements: 1

Replace "x" by "b" in "a"
Expect "a":
"a"
Replacements expected: 0: replacements: 0

Replace "x" by "b" in "x"
Expect "b":
"b"
Replacements expected: 1: replacements: 1

Replace "egregious" by "egregious" in "egregious"
Expect "egregious":
"egregious"
Replacements expected: 1: replacements: 1

Replace "egregious" by "x" in "egregious"
Expect "x":
"x"
Replacements expected: 1: replacements: 1

Testing complete: check output carefully: "Assertion failed" should
not occur!

```
 0
spinoza1111 (3246)
2/14/2010 7:22:30 AM
```On Feb 14, 1:04=A0pm, Joe Wright <joewwri...@comcast.net> wrote:
> Phred Phungus wrote:
> > Joe Wright wrote:
> >> Seebs wrote:
> >>> On 2010-02-13, Chris M. Thomasson <n...@spam.invalid> wrote:
> >>>> I believe that you have a bug in that code Seebs.
>
> >>> Extremely likely.
>
> >>> This is one of the reasons I rely on the standard library -- my
> >>> success rate
> >>> in avoiding fencepost errors is slightly *less* than chance. =A0I'm n=
ot
> >>> actually
> >>> very good at this stuff, which is why I spend so much time thinking
> >>> to do it better.
>
> >>> -s
>
> >> The humility is a good touch. You can use mine.
>
> >> size_t Strlen(char *s)
> >> {
> >> =A0 =A0size_t l =3D 0;
> >> =A0 =A0if (s) while (*s++) l++;
> >> =A0 =A0return l;
> >> }
>
> > So this is your home-rolled strlen?
>
> Yes Fred, it is. Note it is null pointer safe. Anything else?

While it appears to work, it has a showstopper of an error in style,
Joe. This is the use of "l" to mean "length" when in common fonts l
and 1 (the famous number) are different by only one pixel.

of the aliterate.

But hey, what do I know. I write like a fag, and my shit's all fucked
up, right? Right...
> --
> Joe Wright
> "If you rob Peter to pay Paul you can depend on the support of Paul."

```
 0
spinoza1111 (3246)
2/14/2010 7:29:30 AM
```On Feb 14, 2:12=A0pm, spinoza1111 <spinoza1...@yahoo.com> wrote:
> On Feb 14, 7:05=A0am, c...@tiac.net (Richard Harter) wrote:
>
>
>
>
>
> > On Sat, 13 Feb 2010 01:25:27 -0800 (PST),spinoza1111
>
> > <spinoza1...@yahoo.com> wrote:
> > >On Feb 13, 2:46=3DA0am,spinoza1111<spinoza1...@yahoo.com> wrote:
> > >...code...
>
> > >I noticed that in the latest (13 Feb) version of the code, with the
> > >fix to the one-character replace found by Ben B, there were some file
> > >nits: two long lines split and blanks at end of continued macro lines.
>
> > >Let's see if I can get rid of these problems.
>
> > >Also, I misspoke. The failure to handle Ben's example was caused by an
> > >earlier change.
>
> > >Here is the latest code, without the console output.
>
> > I have no particular interest in this programming challenge,
> > though I do find some of the commentary amusing. =A0I thought it
> > might be of interest to do a code review. =A0The following is not
> > an endorsement or a condemnation of the code. =A0Rather it is an
> > informal account of code features that are problematic.
>
> > Notes on the Nilges code:
>
> > (1) At no point is there a comprehensive specification. =A0A fair
> > number of corner cases are left up in the air. =A0These include
> > overlapping targets, and empty targets. =A0There is no statement
> > of error handling strategy. =A0
>
> > (2) There are instances of failure to protect against
> > dereferencing null pointers. =A0Thus in function strLength the for
> > loop will dereference a null pointer if argument strInstring is
> > a null pointer. =A0Similarly function replace checks strTarget but
> > not strMaster. =A0ptrIndex1 is initialized to strMaster. =A0The
> > while loop, while(*ptrIndex1), will dereference a null pointer
> > if strMaster is null. =A0
>
> > The test cases do not check for null arguments nor all instances
> > of empty strings. =A0
>
> > (3) The TESTER macro is cumbersome and should be replaced by a
> > function. =A0
>
> > (4) It would be better if the test cases were moved to a
> > separate file - the plan would be for the main function to read
> > the test cases from from the test cases file and then compare
> > the actual test results with the expected test results. =A0
>
> > more like coding notes written on the spur of the moment to
> > remind the coder about what was going on. =A0There is no statement
> > of the algorithm being used; the comments often reference
> > concepts that are not explained. =A0For example, there is no
> > precise definition of segment nor of handle. =A0
>
> > (6) The commenting format is not well chosen. =A0The comments
> > break into the code and vice versa. =A0
>
> > (7) The code author uses a bizarre, idiosyncratic, and long
> > winded variant of Hungarian notation. =A0It's his privilege. =A0
> > Unfortunately the long names used are not informative. =A0For
> > example, the ptrIndex* variables. =A0What on earth are they, and
> > what are their invariants? =A0The only way to know what they are
> > is play computer, walk through the code, and reconstruct what
> > the coder's intent was. =A0
>
> > Then there are the ptrSegmentStruct variables. =A0One has a suffix
> > of Starts, one of Prev, and one is without a suffix. =A0Since the
> > key idea of the implementation is to generate a linked list of
> > segments, each (except possibly the last) being terminated by
> > the target string, it turns out that the ptrSegmentStructStarts
> > refers to the list head, ptrSegmentStruct refers to the current
> > pointer into the list, and ptrSegmentStructPrev refers to the
> > previous pointer into the list. =A0Or perhaps not. =A0
>
> > (8) The scheme of allocating space for each segment is mildly
> > inefficient, but is much better than reallocing space for the
> > output string. =A0In any case it is doubtful that execution
> > efficiency is among the objectives of this exercise. =A0
>
> > (9) In some places the code is overly complex. =A0A case in point
> > is:
>
> > lngNewLength +=3D ptrSegmentStruct->lngSegmentLength +
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (ptrIndex2 && !*ptrIndex2
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0?
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0lngReplacementLength
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0:
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A00);
>
> > There are several other instances of unnecessary complexity. =A0
> > The updating of the never defined Index variables is a case in
> > point. =A0
>
> > (10) Only one of strNew, strNewStart is needed.
>
> > (11) In conclusion, it is difficult to determine whether the
> > code works correctly because the design is not spelled out, the
> > variables are not properly documention, the testing framework is
> > inadequate, and the baroque nomeclature and coding complicate
> > analysis. =A0
>
> > Richard Harter, c...@tiac.nethttp://home.tiac.net/~cri,http://www.varin=
oma.com
> > Infinity is one of those things that keep philosophers busy when they
> > could be more profitably spending their time weeding their garden.
>
> Looks great, and it looks like I need to review this carefully. I am
> in my morning "pass" through many responses, including responses to

Naw, on first reading, it don't look that great: a lot of pompous
windbaggery in the corporate genre. But I need to go out for a run
before I start torturing quite small animals. I will blow this out of
the water later.
```
 0
spinoza1111 (3246)
2/14/2010 7:31:44 AM
```
spinoza1111 wrote:

> OK, I implemented and tested
> the above-described solution to the "showstopper performance bug" that
> Seebach more or less found.

The change list does not reflect this statement.

w..

--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
```
 0
walter20 (887)
2/14/2010 7:36:45 AM
```"spinoza1111" ha scritto nel messaggio
On Feb 13, 2:46 am, spinoza1111 <spinoza1...@yahoo.com> wrote:
....code...

TESTER(ptrResult,
"a miracle a miraclesnirpKamunkle a Miraclea
miracleamiracle",
"a miracle",
"",
" snirpKamunkle a Miracle",
4,
lngReplacements)

i think it should be:

TESTER(ptrResult,
"a miracle a miraclesnirpKamunkle a Miraclea
miraclea miracle",
^^^^^^^^^^^^^^^^^^
"a miracle",
"",
" snirpKamunkle a Miracle",
4,
lngReplacements)
For the problem; i wrote the routine for doing that
in assembly using in that routine no string.h function

```
 0
io_x
2/14/2010 7:51:03 AM
```Joe Wright wrote:

<snip>

> size_t Strlen(char *s)
> {
>    size_t l = 0;
>    if (s) while (*s++) l++;
>    return l;
> }

This, too, suffers (if that's the right word) from an unnecessary ++. It
also conflates "" and NULL. In a way that's fair enough, provided the
documentation says so (e.g. by warning that a null pointer parameter
invokes undefined behaviour). But we can separate them easily enough
without changing the interface, if we're prepared to think of (size_t)-1
as a sign that something went wrong - and we can eliminate that pesky
redundant ++ at the same time:

#include <stddef.h>
size_t sl(const char*s){size_t l=-1;if(s)do++l;while(s[l]);return l;}

You will note that, in the interests of readability, I have removed as
much whitespace as possible, since nobody can read whitespace.

Note for the terminally thick: DON'T use the above function or any of
the other silly attempts that have been posted in this silly thread. Use
strlen - the real one, the one in the standard library.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
```
 0
rjh (10791)
2/14/2010 7:56:16 AM
```spinoza1111 wrote:
> On Feb 14, 2:15 am, Richard Heathfield <r...@see.sig.invalid> wrote:
>> spinoza1111wrote:
<snip>
>>
>>> ....dishonestly, like Falstaff, seeking glory.
>> The glory involved in pointing out improvements in your code is about at
>> the same level as the glory involved in peeling a banana.
>
> You have suggested no useful improvements.

and ditching a silly and unnecessary strlen replacement. Those are
useful suggestions.

<snip>

>>  > since you found no bugs,
>>
>> I haven't looked yet.
>
> Lazy bastard, aren't you.

I spent many hours trying to educate you about C in large chunks. It's a
waste of time. You don't seem to be able to cope with more than one idea
at a time, and even then it sometimes takes you a few days to understand
it. I have better ways to spend my time.

Or perhaps the code is "unreadable" despite
> all the work I've done?

No, the code is hard to read *because* of all the work you've done
(including the work you did on the first draft).

> You know, I discovered a long time ago that
> there are two types of people who like to call either texts or code

s/two/three/
s/like to //

>
> *  Stupid people employed at positions for which they are not, in
> reality, qualified
>
> *  Criminals who find the law unreadable in hopes of copping a plea of
> plausible deniability

* People who find themselves faced with code that is harder than

<nonsense snipped>

>>  > I thought you wrote portable code. Oh well.
>>
>> I do. You don't know what it means.
>
> What an asshole. Your code can't be pasted and run into common older
> implementations.

It can't be pasted into Fortran programs or APL programs either. So
what? I don't claim portability to non-standard implementations.

> When another's code fails this simple test, you
> condemn their competence,

Actually, no I don't do that. You may be mixing me up with someone else,
or your ignorance of C may have led you to misunderstand an article I've
written. Either is possible. Both is even more possible.

<nonsense snipped>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
```
 0
rjh (10791)
2/14/2010 8:04:44 AM
```spinoza1111 wrote:
> On Feb 14, 2:19 am, Seebs <usenet-nos...@seebs.net> wrote:
<snip>

>>
>> That said, I do like the idiom
>>         size_t lenstr(char *string) {
>>                 char *end = string;
>>                 while (*end++)
>>                         ;
>>                 return end - string;
>>         }
>>
> Doesn't even compile on a "standard" compiler that doesn't support
> initialization in decaration.

That's a contradiction in terms. No such compiler exists.

<snip>

> How DARE you. How DARE you attack Schildt et al. for bugs as if you

Everybody makes stupid mistakes. Schildt is not immune from that, but
neither is anyone else. When professionals make stupid mistakes (and
yes, they do), they don't try to make the situation worse by denying or
covering up the mistake. Schildt's mistake, and it's one which he has
yet to acknowledge as far as I am aware, is that he has failed to
produce a comprehensive errata list for his C books.

<nonsense snipped>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
```
 0
rjh (10791)
2/14/2010 8:11:18 AM
```On 2010-02-14, Richard Heathfield <rjh@see.sig.invalid> wrote:
> Everybody makes stupid mistakes.

I make them more than most people.  As a compensating tactic, I can be pretty
careful about working things out and testing them...  But I tend not to when
posting to Usenet (although I always check my facts before posting nonsense
to Usenet!).

> When professionals make stupid mistakes (and
> yes, they do), they don't try to make the situation worse by denying or
> covering up the mistake.

In general, no.  Someone pointed that one out, and I concede cheerfully that,
yes, that's a pretty stupid mistake.  I make stupid mistakes a *lot*, so I'm
used to that.  Note that I make them a lot less often on much more
complicated things than on simpler things; a neat quirk of brain chemistry
or something.  And I don't just mean "less often, compared to other people"; I
mean less often in absolute terms.  I'm much more likely to get something
trivial wrong than something interesting and challenging.

> Schildt's mistake, and it's one which he has
> yet to acknowledge as far as I am aware, is that he has failed to
> produce a comprehensive errata list for his C books.

I disagree.  The problem is not the lack of an errata list; it's that he
still doesn't even *understand* how feof() works.  He's written a series
of Pascal books which have been cleverly relabeled "C" and had some of the
punctuation altered, in effect.  He got several of the "easy" mistakes that
were, say, posted on my page, fixed for the 4th edition.  He didn't fix the
much more serious logic flaws introduced by his unwillingness to comprehend
how end-of-file conditions are handled in C.

And that's the thing.  Errata would be one thing.  But if every example I
read using feof() used it incorrectly, and multiple examples of how to do
input loops used feof() incorrectly, that suggests to me that these are not
merely "stupid mistakes" (fencepost errors, typos, etcetera), but a genuine
failure to comprehend something which I think can be reasonably regarded as
fairly basic.

-s
--
Copyright 2010, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
```
 0
usenet-nospam (2309)
2/14/2010 8:17:25 AM
```On Feb 14, 3:36=A0pm, Walter Banks <wal...@bytecraft.com> wrote:
> spinoza1111wrote:
> > OK, I implemented and tested
> > the above-described solution to the "showstopper performance bug" that
> > Seebach more or less found.
>
> The change list does not reflect this statement.

Seebach didn't find the SPB: I did.
>
> w..
>
> --- news://freenews.netfront.net/ - complaints: n...@netfront.net ---

```
 0
spinoza1111 (3246)
2/14/2010 8:23:55 AM
```On Feb 14, 3:51=A0pm, "io_x" <a...@b.c.invalid> wrote:
> "spinoza1111" ha scritto nel messaggionews:06317ad6-cd11-48e7-80db-3341ef=
> On Feb 13, 2:46 am,spinoza1111<spinoza1...@yahoo.com> wrote:
> ...code...
>
> =A0 =A0 TESTER(ptrResult,
> =A0 =A0 =A0 =A0 =A0 =A0"a miracle a miraclesnirpKamunkle a Miraclea
> miracleamiracle",
> =A0 =A0 =A0 =A0 =A0 =A0"a miracle",
> =A0 =A0 =A0 =A0 =A0 =A0"",
> =A0 =A0 =A0 =A0 =A0 =A0" snirpKamunkle a Miracle",
> =A0 =A0 =A0 =A0 =A0 =A04,
> =A0 =A0 =A0 =A0 =A0 =A0lngReplacements)
>
> i think it should be:
>
> TESTER(ptrResult,
> =A0 =A0 =A0 =A0 =A0 =A0"a miracle a miraclesnirpKamunkle a Miraclea
> miraclea miracle",
> ^^^^^^^^^^^^^^^^^^
> =A0 =A0 =A0 =A0 =A0 =A0"a miracle",
> =A0 =A0 =A0 =A0 =A0 =A0"",
> =A0 =A0 =A0 =A0 =A0 =A0" snirpKamunkle a Miracle",
> =A0 =A0 =A0 =A0 =A0 =A04,
> =A0 =A0 =A0 =A0 =A0 =A0lngReplacements)
> For the problem; i wrote the routine for doing that
> in assembly using in that routine no string.h function

(1) I am not qualified to read assembler (note that that's how a
gentlemen speaks when he is not qualified to read code: he doesn't

(2) The problem was to be solved in C

```
 0
spinoza1111 (3246)
2/14/2010 8:26:19 AM
```"Joe Wright" <joewwright@comcast.net> ha scritto nel messaggio
> Seebs wrote:
>> On 2010-02-13, Chris M. Thomasson <no@spam.invalid> wrote:
>>> I believe that you have a bug in that code Seebs.
>>
>> Extremely likely.
>>
>> This is one of the reasons I rely on the standard library -- my success rate
>> in avoiding fencepost errors is slightly *less* than chance.  I'm not
>> actually
>> very good at this stuff, which is why I spend so much time thinking about how
>> to do it better.
>>
>> -s
>
> The humility is a good touch. You can use mine.
>
> size_t Strlen(char *s)
> {
>    size_t l = 0;
>    if (s) while (*s++) l++;
>    return l;
> }

good, with that it is easy to add error managment

//  -1  on error
size_t Strlen(char *s)
{ size_t l = 0;
if (s) while (*s++)
{if(s==0)  return  (size_t)-1;
l++;
if(l==0)    return (size_t)-1;
}
return l;
}

> --
> Joe Wright
> "If you rob Peter to pay Paul you can depend on the support of Paul."

```
 0
io_x
2/14/2010 8:28:19 AM
```"io_x" <a@b.c.invalid> ha scritto nel messaggio
>
> "spinoza1111" <spinoza1111@yahoo.com> ha scritto nel messaggio
> // ---------------------------------------------------------------
> // Statement-format test macro
> //
> //
> #define TESTER(resultPtr, master, target, replacement, expected,
> expectedReplacements, replacements) \
> { \
>    printf("Replace \"%s\" by \"%s\" in \"%s\"\n", \
>           (target), (replacement), (master)); \
>    printf("Expect \"%s\":\n       \"%s\"\n", \
>           (expected), \
>           resultPtr = replace((master), \
>                               (target), \
>                               (replacement), \
>                               &(replacements))); \
>    printf("Replacements expected: %d: replacements: %d\n", \
>           (expectedReplacements), \
>           (replacements)); \
>    if (!(strLength(resultPtr) \
>        == \
>        strLength(master) \
>        + \
>        (strLength(replacement)-strLength(target)) \
>        * \
>        replacements)) \
>        printf("Assertion failed\n"); \
>    printf("\n\n"); \
>    free(resultPtr); \
> }
>
> I can not be agree on your way of build test function
> like a macro: that is indebuggable.
> Macro for me are for build one language or for doing little
> substitution like in "P" ---> "printf"
>
> this is my propose: write only when find one error
> --------------------------------
> #define  P  printf
> #define  R  return
>
> // origin has to came from malloc memory
> int  tester(char* origin, char*  whatSost, char*  sost, char*  expected)
> {char     *p;
> unsigned len;

is seen this post?

```
 0
io_x
2/14/2010 8:28:49 AM
```On Feb 14, 4:17=A0pm, Seebs <usenet-nos...@seebs.net> wrote:
> On 2010-02-14, Richard Heathfield <r...@see.sig.invalid> wrote:
>
> > Everybody makes stupid mistakes.
>
> I make them more than most people. =A0As a compensating tactic, I can be =
pretty
> careful about working things out and testing them... =A0But I tend not to=
when
> posting to Usenet (although I always check my facts before posting nonsen=
se
> to Usenet!).
>
> > When professionals make stupid mistakes (and
> > yes, they do), they don't try to make the situation worse by denying or
> > covering up the mistake.
>
> In general, no. =A0Someone pointed that one out, and I concede cheerfully=
that,
> yes, that's a pretty stupid mistake. =A0I make stupid mistakes a *lot*, s=
o I'm
> used to that. =A0Note that I make them a lot less often on much more
> complicated things than on simpler things; a neat quirk of brain chemistr=
y
> or something. =A0And I don't just mean "less often, compared to other peo=
ple"; I
> mean less often in absolute terms. =A0I'm much more likely to get somethi=
ng
> trivial wrong than something interesting and challenging.

Why are you so self-centered? We're really not very interested in your
brain chemistry. The problem is the effect of your malicious and self-
serving behavior on others.
>
> > Schildt's mistake, and it's one which he has
> > yet to acknowledge as far as I am aware, is that he has failed to
> > produce a comprehensive errata list for his C books.
>
> I disagree. =A0The problem is not the lack of an errata list; it's that h=
e
> still doesn't even *understand* how feof() works. =A0He's written a serie=
s
> of Pascal books which have been cleverly relabeled "C" and had some of th=
e
> punctuation altered, in effect. =A0He got several of the "easy" mistakes =
that
> were, say, posted on my page, fixed for the 4th edition. =A0He didn't fix=
the
> much more serious logic flaws introduced by his unwillingness to comprehe=
nd
> how end-of-file conditions are handled in C.

Given your failures to comprehend issues and simple mistakes, you're
without standing to write this paragraph. Part of the purpose of C was
to enable a "pascal" style in that it was supposed to be a safer
language than PL/I.
>
> And that's the thing. =A0Errata would be one thing. =A0But if every examp=
le I
> read using feof() used it incorrectly, and multiple examples of how to do
> input loops used feof() incorrectly, that suggests to me that these are n=
ot
> merely "stupid mistakes" (fencepost errors, typos, etcetera), but a genui=
ne
> failure to comprehend something which I think can be reasonably regarded =
as
> fairly basic.
>
> -s
> --
> Copyright 2010, all wrongs reversed. =A0Peter Seebach / usenet-nos...@see=
bs.nethttp://www.seebs.net/log/<-- lawsuits, religion, and funny picturesht=
tp://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!

```
 0
spinoza1111 (3246)
2/14/2010 9:27:43 AM
```spinoza1111 wrote:

<usual drivel snipped>

> Part of the purpose of C was
> to enable a "pascal" style in that it was supposed to be a safer
> language than PL/I.

Can you provide independent authoritative evidence for this rather
strange claim?

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
```
 0
rjh (10791)
2/14/2010 9:37:11 AM
```On Feb 14, 7:05=A0am, c...@tiac.net (Richard Harter) wrote:
> On Sat, 13 Feb 2010 01:25:27 -0800 (PST),spinoza1111
>
> <spinoza1...@yahoo.com> wrote:
> >On Feb 13, 2:46=3DA0am,spinoza1111<spinoza1...@yahoo.com> wrote:
> >...code...
>
> >I noticed that in the latest (13 Feb) version of the code, with the
> >fix to the one-character replace found by Ben B, there were some file
> >nits: two long lines split and blanks at end of continued macro lines.
>
> >Let's see if I can get rid of these problems.
>
> >Also, I misspoke. The failure to handle Ben's example was caused by an
> >earlier change.
>
> >Here is the latest code, without the console output.
>
> I have no particular interest in this programming challenge,
> though I do find some of the commentary amusing. =A0I thought it
> might be of interest to do a code review. =A0The following is not
> an endorsement or a condemnation of the code. =A0Rather it is an
> informal account of code features that are problematic.
>
> Notes on the Nilges code:
>
> (1) At no point is there a comprehensive specification. =A0A fair
> number of corner cases are left up in the air. =A0These include
> overlapping targets, and empty targets. =A0There is no statement
> of error handling strategy. =A0

If you mean in the code, this is FALSE. These issues were handled and
they were discussed. RTFT

And since when was a "comprehensive specification" required in the
documentation? No other code even comes close to the utility and
completeness of the comments in this code. Sure, they could be
improved: but do note that any actual improvements would make the
documentation less "readable" using the demotic (and quite ignorant)
definition of "readability" used by many posters here.

>
> (2) There are instances of failure to protect against
> dereferencing null pointers. =A0Thus in function strLength the for
> loop will dereference a null pointer if argument strInstring is
> a null pointer. =A0Similarly function replace checks strTarget but
> not strMaster. =A0ptrIndex1 is initialized to strMaster. =A0The
> while loop, while(*ptrIndex1), will dereference a null pointer
> if strMaster is null. =A0

This is correct. But note that you're subjecting the code to a more
exacting standard that any other competitor meets, or for that matter
99% of C programs (which typically will fail if passed a null
function), out of personal malice, animosity, and envy...of the fact
that I can do two things seldom mastered simultaneously: write like a
humanist and code better than you.

Seriously, how many times have you checked for a NULL parameter
explicitly?

This issue is fabricated. Even quality library programs don't compare
to NULL; instead, a failure occurs inside the library code. It's
arguably a good practice, but its implementation in my code needs a
more general strategy for handling errors.

Your goal is "destroy Nilges, because he can do our job and the guy
doesn't even know C! He can also write a complex sentence! Nilges must
die!"

>
> The test cases do not check for null arguments nor all instances
> of empty strings. =A0

Twenty lashes with a wet noodle.

Clown.

OK, so code them in the idioms supported and post them, and I will add
them. What part of collaboration don't you understand?

>
> (3) The TESTER macro is cumbersome and should be replaced by a
> function. =A0

It is no more cumbersome than the lumber in your brain. I'm tired of
little coding monkeys who cover up their lack of energy with big words
used unconsciously-metaphorically.

However, it could I suppose be a function as I scale up.

>
> (4) It would be better if the test cases were moved to a
> separate file - the plan would be for the main function to read
> the test cases from from the test cases file and then compare
> the actual test results with the expected test results. =A0

The test software shouldn't become the main focus. It should be
simple, otherwise we get into an infinite regress.

>
> more like coding notes written on the spur of the moment to
> remind the coder about what was going on. =A0There is no statement
> of the algorithm being used; the comments often reference
> concepts that are not explained. =A0For example, there is no
> precise definition of segment nor of handle. =A0

If you mean, in "read like coding notes", the change record, that is
what they are. I don't cover up my bugs, nor grin about them like
Seebie. As for the remainder, I mean to generate software by writing
first, coding later, and providing an audit trail. Of course, the
comments could and should be cleaned up were I to publish the code,
but again: you invent ad-hoc criteria, meant to be applied ONLY to
this code, out of adversarial hatred, envy and malice. In a court of
law, you'd be in contempt.

>
> (6) The commenting format is not well chosen. =A0The comments
> break into the code and vice versa.

Incoherent.=A0
>
> (7) The code author uses a bizarre, idiosyncratic, and long
> winded variant of Hungarian notation. =A0It's his privilege. =A0

Damn straight. I am the King of Hungary.

> Unfortunately the long names used are not informative. =A0For
> example, the ptrIndex* variables. =A0What on earth are they, and
> what are their invariants? =A0The only way to know what they are
> is play computer, walk through the code, and reconstruct what
> the coder's intent was. =A0

No, it just needs a read of the code. ptr is a pointer MEANT TO BE
MODIFIED, as opposed to str, which is a pointer to a char meant not to
be modified. Some C programmers in these threads would suggest const
for the latter, but others have discouraged its use.

You are in fact conducting the sort of "structured walkthru" that in
my experience appeared at Bell Northern Research after the election of
Reagan, one in which issues were fabricated ad-hoc out of hatred, envy
and malice because Northern Telecom executives (some of whom later
went to jail) were forcing different BNR sites to compete with each
other so they could get fat bonuses and live like swine...while former
members of the scientific staff at Mountain View die in motels without
health insurance.

I've already explained how easy it is for a competent tech, using a
modern era (or even emacs) to globally scan/replace ptrIndex1 to
index1, or whatever he wants. If I were coding in an office that
mandated in its standard manual, or as an oral rule, either "no
Hungarian" or "Szymonyi Hungarian" as opposed to my standard (which
happens to have been invented inside IBM when Charles Szymonyi was
failing to adjust to socialism, and which was stolen and modified by
him), I would use the office standard.

What part of "red herring" don't you understand?

>
> Then there are the ptrSegmentStruct variables. =A0One has a suffix
> of Starts, one of Prev, and one is without a suffix. =A0Since the

Wow. His shit's all fucked up.

> key idea of the implementation is to generate a linked list of
> segments, each (except possibly the last) being terminated by

OK, so far.

> the target string, it turns out that the ptrSegmentStructStarts
> refers to the list head, ptrSegmentStruct refers to the current
> pointer into the list, and ptrSegmentStructPrev refers to the
> previous pointer into the list. =A0Or perhaps not. =A0

Or perhaps not (and screw your irony). It's a perfectly meaningful
triad of names. We need to know the first entry (Starts) to assemble
the output string. We need to walk the structure with the unsuffixed
name. And the Prev pointer, which is inactive and unused after the
scan for target loop, is initialized correctly to zero so that the
append can be written properly:

if (ptrSegmentStructPrev !=3D 0)
ptrSegmentStructPrev->ptrNext =3D ptrSegmentStruct;
else
ptrSegmentStructStarts =3D ptrSegmentStruct;

The use of Prev is perfectly guarded in the above. Do you in fact know
how to construct a linked list (Heathfield can't)?

At some point in the distant past, Harter, you were able to write
competent code, for I saw an old 1990 program of yours that was
competent. I think you are now some sort of manager who is today
unable, unlike me, to crank this level of code in the time I
took...about two hours for the first version, and a total of 8..10
hours thereafter. I conclude that you are hand-waving and using
corporatese out of hatred, envy and malice. What's disturbing is that
the appearance of hatred, envy and malice in code reviews first
appeared in my experience on the job after Reagan was elected, and
companies made programmers into perpetual infants, always candidates
for their posts, whereas today, people air their hatred, envy and

>
> (8) The scheme of allocating space for each segment is mildly
> inefficient, but is much better than reallocing space for the
> output string. =A0In any case it is doubtful that execution
> efficiency is among the objectives of this exercise. =A0

You are so full of hatred, envy and malice that you cannot be in the
neutral corporate prose.

At least you can spell "efficient".

Given the objectives, the only "inefficiency" was fixed this morning.
This was the generation of zero length segments.

As you seem to know, a realloc would involve to many memory copies,
unbounded apriori. Whereas the assembly of the final string takes M
mallocs for the segments (where M =3D=3D the number of targets that are
not immediately preceded by > 1 targets) and one malloc for the final
string, and minimal motion of bytes to the new string.

>
> (9) In some places the code is overly complex. =A0A case in point
> is:
>
> lngNewLength +=3D ptrSegmentStruct->lngSegmentLength +
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (ptrIndex2 && !*ptrIndex2
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0?
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0lngReplacementLength
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0:
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A00);
>
> There are several other instances of unnecessary complexity.

What you mean is that there are no longer any programmers in fact
considerate enough of their intelligent readers to take the trouble to
so format code under the (rather severe) 67 character line limit
imposed by the newsreaders. Two-dimensional formatting in fact is a
great way to exhibit  operator precedence.

It is true that one of these statements is munged in the current
edition of the code (and only one), but a competent technician knows
how to fix this based on the consistency of the style, a consistency
that appears to apes as unnecessary complexity.

You see, dear chap, what you mean by "unnecessary complexity" is in
fact any evidence of thought or work. Because data processing has
become a pure cost center, executives are troubled by evidence of
thought or work on the part of which has become a pure eunuch class,
charged with pure software maintenance and the chanting of hymns and
anthems to capitalism.

=A0
> The updating of the never defined Index variables is a case in
> point. =A0
>
> (10) Only one of strNew, strNewStart is needed.

You don't know what you're talking about, and you have not diligently
or adequately studied the code.  strNew is needed to index through the
new string, whereas we need to return strNewStart.

"Never defined Index variables" is gibberish.

In fine, although I expected better from you, you've Swift Boated the
code, creating a pompous document that will be used by subsequent
posters as "evidence". It's the same sort of document that Seebie used
to swift boat Schildt.

What a jerk!

>
> (11) In conclusion, it is difficult to determine whether the
> code works correctly because the design is not spelled out, the
> variables are not properly documention, the testing framework is
> inadequate, and the baroque nomeclature and coding complicate
> analysis. =A0

Pompous, meaningless bullshit. For example, most corporate types who
use the word "baroque" couldn't identify Baroque music or art in a
simple test. Here, it means "my God, someone is thinking originally.
Kill him!"
>
> Richard Harter, c...@tiac.nethttp://home.tiac.net/~cri,http://www.varinom=
a.com
> Infinity is one of those things that keep philosophers busy when they
> could be more profitably spending their time weeding their garden.

```
 0
spinoza1111 (3246)
2/14/2010 10:15:15 AM
```On Sat, 13 Feb 2010 23:29:30 -0800, spinoza1111 wrote:

> On Feb 14, 1:04 pm, Joe Wright <joewwri...@comcast.net> wrote:
>> Phred Phungus wrote:
>> > Joe Wright wrote:
>> >> Seebs wrote:
>> >>> On 2010-02-13, Chris M. Thomasson <n...@spam.invalid> wrote:
>> >>>> I believe that you have a bug in that code Seebs.
>>
>> >>> Extremely likely.
>>
>> >>> This is one of the reasons I rely on the standard library -- my
>> >>> success rate
>> >>> in avoiding fencepost errors is slightly *less* than chance.  I'm
>> >>> not actually
>> >>> very good at this stuff, which is why I spend so much time thinking
>> >>> to do it better.
>>
>> >>> -s
>>
>> >> The humility is a good touch. You can use mine.
>>
>> >> size_t Strlen(char *s)
>> >> {
>> >>    size_t l = 0;
>> >>    if (s) while (*s++) l++;
>> >>    return l;
>> >> }
>>
>> > So this is your home-rolled strlen?
>>
>> Yes Fred, it is. Note it is null pointer safe. Anything else?
>
> While it appears to work, it has a showstopper of an error in style,
> Joe. This is the use of "l" to mean "length" when in common fonts l and
> 1 (the famous number) are different by only one pixel.
>
> the aliterate.

FTFY:

size_t Strlen(char *StrTheStringThatNeedsToBeMeasuredButWhomsNameCannotBeSpoken)
{
size_t SizTheLengthOfTheStringThatNeedsToBeMeasuredButWhomsNameCannotBeSpoken = 0;

if (StrTheStringThatNeedsToBeMeasuredButWhomsNameCannotBeSpoken)
while (*StrTheStringThatNeedsToBeMeasuredButWhomsNameCannotBeSpoken++)
SizTheLengthOfTheStringThatNeedsToBeMeasuredButWhomsNameCannotBeSpoken++;

return SizTheLengthOfTheStringThatNeedsToBeMeasuredButWhomsNameCannotBeSpoken;

}

HTH,
AvK
```
 0
root32 (398)
2/14/2010 11:06:33 AM
```In article <d86dne32P5jZGerWnZ2dnUVZ_vidnZ2d@giganews.com>,
Joe Wright  <joewwright@comcast.net> wrote:

>> So this is your home-rolled strlen?

>Yes Fred, it is. Note it is null pointer safe.

For some value of "safe".  I'd rather get a segmentation fault,
so that I detect my mistake sooner.

Of course, you could consistently treat a null pointer as equivalent
to an empty string, but you'd need a complete suite of similarly
modified string functions.  You'd want Strcmp("", 0) to be 0, and
Printf("%s", (char *)0) to print nothing, and so on.

-- Richard
--
Please remember to mention me / in tapes you leave behind.
```
 0
richard91 (3692)
2/14/2010 11:07:40 AM
```In article <hl8lhs\$fgj\$3@pc-news.cogsci.ed.ac.uk>, I wrote:

>In article <d86dne32P5jZGerWnZ2dnUVZ_vidnZ2d@giganews.com>,
>Joe Wright  <joewwright@comcast.net> wrote:

>>> So this is your home-rolled strlen?

>>Yes Fred, it is. Note it is null pointer safe.

>For some value of "safe".  I'd rather get a segmentation fault,
>so that I detect my mistake sooner.

By the way, I didn't mean to imply that Joe was seriously suggesting
that anyone use his function.  I just wanted to make the point about
"null pointer safe".

-- Richard
--
Please remember to mention me / in tapes you leave behind.
```
 0
richard91 (3692)
2/14/2010 11:10:39 AM
```In article <f3dd4ed8-600b-44cc-8f01-4ae6b910a71b@l24g2000prh.googlegroups.com>,
spinoza1111  <spinoza1111@yahoo.com> wrote:
>"You talk like a fag, and you're shit's all fucked up." - Idiocracy,
>Mike Judge, 2005

Paraphrasing again?
"You talk like a fag, and your shit's all retarded" - Idiocracy,
Mike Judge, 2006
```
 0
ike5 (224)
2/14/2010 12:21:59 PM
```On Feb 14, 10:26=A0am, spinoza1111 <spinoza1...@yahoo.com> wrote:
>
> (1) I am not qualified to read assembler (note that that's how a
> gentlemen speaks when he is not qualified to read code: he doesn't
>
That would imply that there is an esoteric or highly professional body
of knowledge called "assembler" which requires a logn apprenticeship
to learn.
"I can't read assembler" or, more likely, "I'm unfamiliar with this
particular assembler" is the better response.
```
 0
2/14/2010 12:34:08 PM
```On Feb 14, 4:17=A0pm, Seebs <usenet-nos...@seebs.net> wrote:
> On 2010-02-14, Richard Heathfield <r...@see.sig.invalid> wrote:
>
> > Everybody makes stupid mistakes.
>
> I make them more than most people. =A0As a compensating tactic, I can be =
pretty
> careful about working things out and testing them... =A0But I tend not to=
when
> posting to Usenet (although I always check my facts before posting nonsen=
se
> to Usenet!).
>
> > When professionals make stupid mistakes (and
> > yes, they do), they don't try to make the situation worse by denying or
> > covering up the mistake.
>
> In general, no. =A0Someone pointed that one out, and I concede cheerfully=
that,
> yes, that's a pretty stupid mistake. =A0I make stupid mistakes a *lot*, s=
o I'm
> used to that. =A0Note that I make them a lot less often on much more
> complicated things than on simpler things; a neat quirk of brain chemistr=
y
> or something. =A0And I don't just mean "less often, compared to other peo=
ple"; I
> mean less often in absolute terms. =A0I'm much more likely to get somethi=
ng
> trivial wrong than something interesting and challenging.
>
> > Schildt's mistake, and it's one which he has
> > yet to acknowledge as far as I am aware, is that he has failed to
> > produce a comprehensive errata list for his C books.
>
> I disagree. =A0The problem is not the lack of an errata list; it's that h=
e
> still doesn't even *understand* how feof() works. =A0He's written a serie=
s
> of Pascal books which have been cleverly relabeled "C" and had some of th=
e
> punctuation altered, in effect. =A0He got several of the "easy" mistakes =
that
> were, say, posted on my page, fixed for the 4th edition. =A0He didn't fix=
the
> much more serious logic flaws introduced by his unwillingness to comprehe=
nd
> how end-of-file conditions are handled in C.
>
> And that's the thing. =A0Errata would be one thing. =A0But if every examp=
le I
> read using feof() used it incorrectly, and multiple examples of how to do

In Herb's defense, I'd say that intelligent people find it hard to
treat mistakes (such as the design of feof) with respect, and enough
to remember the deviant implementation that feof is. Herb's failure to
recall to mind a massive boner means he's an intelligent person.
Whereas nasty little clerks (who as we saw this morning make their own
stupid mistakes, but expect to be forgiven) take a sour delight in
"learning" clap trap.

This isn't programming, Seebach. It's Trainspotting.

An intelligent programmer, when confronted with the incredibly poor
design of feof, turns right around and changes feof into a simple
macro:

He then can forget the design error, which is normalized deviance from
hell, since it forces the program to try to read SOMETHING to detect
IO. On any number of environments, this can change the state of the
underlying hardware in unpredictable ways. Even if the hardware can
signal to the runtime "don't you dare try to read from me, I have
nothing for you now", the C runtime HAS TO READ,  which can easily
throw off auditing software or firmware, recording in all cases one

Someone late at night has then to remember, while nodding weak and
weary, that oh yeah, this is a C program.

How many ruined marriages, late nights, alcoholic benders, and
suicides has this caused? How many little, stunted, substance abusing
and creepy personalities has this caused? And why do people think that
knowing these coding horrors is anything but an expense of spirit in a
waste of shame?

Herb should have done a better job, but the error is so common among
good programmers and intelligent people so as to cast the aspersion on
C and standards committee members too cowardly and incompetent to fix
it.

In case you hadn't noticed, the only reason for using a programming
language is to make programming intellectually manageable. The blame
lies upon the designers of C, and you had NO STANDING in pretending to
suitable academic preparation thereby. You should have been taking
evening classes in comp sci. You especially have NO STANDING in light

The intended meaning of "C: The Complete Nonsense" was "look at me, I
am more qualified than Herb Schildt". But your errors in this thread,
and your failure to post decent code, means that you are far LESS
qualified.

You blame Herb for not publishing errata. New editions trump errata.
Sure, he should have fixed the bug: but what about the refusal of the
C standardizers to reform the numerous errors in C? I'd say this is
the greater crime, because again, the only reason for using a high
level language is to make problems intellectually manageable.

I've shown that this is possible in C with the replace() example this
week. My solution (and only my solution) showed  aspects of the
problem which other solutions concealed. Had I been Herb, I would have
addressed the feof() issue head-on, but I'm not, and it may be that he
didn't want to confuse his readers.

But in light of how frequent feof() errors are (see the first Google
hit for "feof C" at http://www.cplusplus.com/reference/clibrary/cstdio/feof=
/:
it warns about the behavior of this turkey and then has a code sample
with the classic error), it was in fact libel for you to try to make
this global and normalized deviance stick to Schildt.

You have TWICE in the past week posted trivial code snippets with
errors (%s and off by one strlen). You had NO STANDING ten years ago,
and you have NO STANDING now in talking about other people's errors,
especially because with regards to McGraw Hill and here, you act like
an infant, refusing to work collaboratively and compassionately with
others while expecting us to have compassion for your oh-so-precious
and oh-so-unique personality disorders.

You need to WITHDRAW and APOLOGIZE FOR the "C: The Complete Nonsense".
NOW.

> input loops used feof() incorrectly, that suggests to me that these are n=
ot
> merely "stupid mistakes" (fencepost errors, typos, etcetera), but a genui=
ne
> failure to comprehend something which I think can be reasonably regarded =
as
> fairly basic.

This is your self-serving interpretation. However,

*  Posting a solution that is supposed to replace %s and replaces
instead all percents and the character following them, which may cause
a memory fault,

*  Posting a strlen replacement which managed to be off by one in a
few short lines of code,

*  Claiming that "the 'Heap' is a DOS term",

*  Consistently asking forgiveness for errors whilst uncharitably
withholding it from colleagues,

*  Being ignorant of the use of concrete memory layouts of stacks and
heaps in classrooms to explain how runtimes work,

*  Throwing away email from Apress colleagues unread, and calling them
"morons" and impugning their credibility and sanity online

indicates a far more troubling personality.

>
> -s
> --
> Copyright 2010, all wrongs reversed. =A0Peter Seebach / usenet-nos...@see=
bs.nethttp://www.seebs.net/log/<-- lawsuits, religion, and funny picturesht=
tp://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
```
 0
spinoza1111 (3246)
2/14/2010 5:22:22 PM
```On Feb 14, 8:21=A0pm, i...@localhost.claranet.nl (Ike Naar) wrote:
..com>,
>
> spinoza1111=A0<spinoza1...@yahoo.com> wrote:
> >"You talk like a fag, and you're shit's all fucked up." - Idiocracy,
> >Mike Judge, 2005
>
> Paraphrasing again?
> "You talk like a fag, and your shit's all retarded" - Idiocracy,
> Mike Judge, 2006

Yes, correction accepted. I also screwed up the grammar. Your, not
you're.

```
 0
spinoza1111 (3246)
2/14/2010 5:23:47 PM
```On Sun, 14 Feb 2010 02:15:15 -0800 (PST), spinoza1111
<spinoza1111@yahoo.com> wrote:

>On Feb 14, 7:05=A0am, c...@tiac.net (Richard Harter) wrote:
[snip]
>
> At some point in the distant past, Harter, you were able to
> write competent code, for I saw an old 1990 program of yours
> that was competent.  I think you are now some sort of
> manager

Chortle.  Excuse me while I go whip some slaves, er,

> who is today unable, unlike me, to crank this level
> of code in the time I took...about two hours for the first
> version, and a total of 8..10 hours thereafter.

I certainly hope that I am never able to crank out that
level of code, regardless of the time it takes.

[snip]

>>
>> (10) Only one of strNew, strNewStart is needed.
>
>You don't know what you're talking about, and you have not diligently
>or adequately studied the code.  strNew is needed to index through the
>new string, whereas we need to return strNewStart.

You are right.  Mea culpa.
>
>"Never defined Index variables" is gibberish.

Well, no, it's not.  In the C standard "defined" has a very
specific, parochial meaning.   More generally, however, the
definition of a variable is a description of its usage in the
code.  A comprehensive definition includes such things as the
invariants and constraints associated with the variable, and the
kind of things it represents.

There seldom is a need for elaborate definitions.  Often none is
wanted.  Often, however, the presence of an explicit definition
makes a lot of difference, both in reading the code and writing.
The absence of explicit definitions can lead to nasty, obscure
bugs.

It occurs to me that you did not recognize "Index variables" as
shorthand for the variables named ptrIndex0, etc.  If that is
what you were on about, that was what was meant.

```
 0
cri (1432)
2/14/2010 5:30:24 PM
```On 2010-02-14, Richard Harter <cri@tiac.net> wrote:
> On Sun, 14 Feb 2010 02:15:15 -0800 (PST), spinoza1111
><spinoza1111@yahoo.com> wrote:
>> who is today unable, unlike me, to crank this level
>> of code in the time I took...about two hours for the first
>> version, and a total of 8..10 hours thereafter.

> I certainly hope that I am never able to crank out that
> level of code, regardless of the time it takes.

And I certainly hope I never reach a point where a ten-minute project
takes two hours to write and maybe 8-10 hours thereafter to produce an
elaborate, complicated, inefficient, version which we still aren't totally
sure works.

-s
--
Copyright 2010, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
```
 0
usenet-nospam (2309)
2/14/2010 5:44:52 PM
```On Feb 10, 12:54=A0pm, Dann Corbit <dcor...@connx.com> wrote:
> In article <slrnhn628c.o3u.usenet-nos...@guild.seebs.net>, usenet-
> nos...@seebs.net says...
> > This may have gotten buried given that it started in a Nilges thread,
> > but it's actually pretty interesting.
>
> > There was some discussion of algorithms to perform the task:
> > =A0 =A0Inputs: =A0target string, replacement string, original string
> > =A0 =A0Output: =A0a newly-allocated string containing the original
> > =A0 =A0 =A0string with each copy of the target string replaced with the
> > =A0 =A0 =A0replacement string.
>
> > Here's a hunk of mine:
>
> > =A0 =A0 =A0 =A0 for (count =3D 0, t =3D strstr(target, in); t && *t; t =
=3D strstr(t, in)) {
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ++count;
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 t +=3D inlen;
> > =A0 =A0 =A0 =A0 }

Yeah fantastic -- because you are using C strings, you are forced to
execute this in two passes, one to figure out how much space to
allocation and the second to do the copies.

> > Here's a hunk of another one:
>
> > > =A0 =A0 ptrIndex1 =3D strMaster;
> > > =A0 =A0 while(*ptrIndex1)
> > > =A0 =A0 {
> > > =A0 =A0 =A0 =A0 ptrIndex0 =3D ptrIndex1;
> > > =A0 =A0 =A0 =A0 while (-1)
> > > =A0 =A0 =A0 =A0 {
> > > =A0 =A0 =A0 =A0 =A0 =A0 for(;
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex1 && *ptrIndex1 !=3D *strTar=
get;
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ptrIndex1++);
> > > =A0 =A0 =A0 =A0 =A0 =A0 for(ptrIndex2 =3D strTarget, ptrIndex3 =3D pt=
rIndex1;
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex3
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 &&
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex2
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 &&
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex3 =3D=3D *ptrIndex2;
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ptrIndex3++, ptrIndex2++);
> > > =A0 =A0 =A0 =A0 =A0 =A0 if (!*ptrIndex2) break;
> > > =A0 =A0 =A0 =A0 =A0 =A0 ptrIndex1 =3D ptrIndex3;
> > > =A0 =A0 =A0 =A0 =A0 =A0 if (!*ptrIndex3) break;
> > > =A0 =A0 =A0 =A0 }
>
> > These hunks are essentially performing the same part of the core loop;
> > find the next occurrence of the target string in the original string.
>
> > The second one was written by Edward Nilges ("spinoza1111"). =A0He offe=
rs
> > in its defense the assertion that it's the "best" algorithm. =A0(Neverm=
ind
> > that it's got a bug; the bug could be fixed easily.)
>
> > My thinking:
>
> > The first is better, not because it's less buggy (that could be fixed),=
but

Both are using C strings and suffer from the stupidity of not being
able to use lengths to accelerate the performance of any portion of
this algorithm.  "Efficiency and the standard library" is an
oxymoron.  Compare this to the implementation in the Better String
Library.

> For a standard library, the *most* important thing is correctness.

How can one implement gets() correctly?

> [...]=A0IOW, a bsearch() function that is blazing fast but fails if there=
are
> more than 2 billion items is not as good as one that is only half as fast
> but works with anything up to size_t (-1) number of elements.
>
> Assuming correctness, then efficiency should be the next decider.

And what if the specification of the C library does not allow the
algorithm to be implemented efficiently?

> [...]=A0An
> interesting project would be to take a collection of all public C
> libraries and do the following:
> 1. Exhaustively test for correctness

How would you test gets() for correctness.

The Better String Library, on the other hand *COMES WITH* a unit test
that does a reasonable amount of testing.  *Correctness* is also a
more usefully defined concept in the Better String Library (every
function must support all possible parametric inputs so long as each
of the contents of the parameters are independently valid with respect
to their own type.)

If the ANSI C language committee were forced to ship a unit test for
the C standard library, it would probably be a very different
language.

> 2. Analyze for efficiency

Even if it doesn't make any sense to do so?  qsort(), for example, is
*NEVER* efficient in any circumstance.  Nearly the full complement of
string functions are easily beat by the portable "Better String
Library" implementation (note that the latest hand optimized x86
assembly language libraries for the Intel/Microsoft have managed to
catch up to the Better String Library in a few cases, but only by
using esoteric instructions.)

> 3. Choose best of breed from the above analysis. =A0It could also be a
> hybrid (e.g. a decider function chooses the best algorithm based on
> conditions).

If the libraries are written in assembly language (which in Intel and
Microsoft's case is true) does that make sense in your comparison?
You could only say that a library was good on a particular platform.

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/
```
 0
websnarf (1153)
2/14/2010 11:33:58 PM
```"websnarf" <websnarf@gmail.com> wrote in message
On Feb 10, 12:54 pm, Dann Corbit <dcor...@connx.com> wrote:
> > In article <slrnhn628c.o3u.usenet-nos...@guild.seebs.net>, usenet-
> > nos...@seebs.net says...
> > > This may have gotten buried given that it started in a Nilges thread,
> > > but it's actually pretty interesting.
> >
> > > There was some discussion of algorithms to perform the task:
> > > Inputs: target string, replacement string, original string
> > > Output: a newly-allocated string containing the original
> > > string with each copy of the target string replaced with the
> > > replacement string.
> >
> > > Here's a hunk of mine:
> >
> > > for (count = 0, t = strstr(target, in); t && *t; t = strstr(t, in)) {
> > > ++count;
> > > t += inlen;
> > > }

> Yeah fantastic -- because you are using C strings, you are forced to
> execute this in two passes, one to figure out how much space to
> allocation and the second to do the copies.

Well, you are not necessarily "forced" to loop on `strstr()' in two phases.
One can cache the results such that a second round of `strstr()' calls can
be completely eliminated. I created a crude little program that does this:

This has to improve things a little bit...

;^)

> > > Here's a hunk of another one:

[...]

> Both are using C strings and suffer from the stupidity of not being
> able to use lengths to accelerate the performance of any portion of
> this algorithm.

Humm... Of course one can use C strings in conjunction with a length.
Perhaps something like this crap:
_________________________________________________________________
#include <stdio.h>

struct string
{
size_t length;
char* buffer;
};

#define STRING(mp_name, mp_len, mp_content) \
char mp_name ## _temp mp_len = mp_content; \
struct string mp_name = \
{ \
sizeof(mp_name ## _temp) - 1, \
mp_name ## _temp \
}

#define STRING_CONST_FROM_CSTR(mp_name, mp_str) \
struct string const mp_name = \
{ \
sizeof(mp_str) - 1, \
mp_str \
}

int main()
{
STRING(mutable_string, [], "Hello World! (mutable)");

STRING_CONST_FROM_CSTR(inmutable_string, "Hello World! (inmutable)");

printf("mutable_string(%lu) = %s\n"
"inmutable_string(%lu) = %s\n",
(unsigned long)mutable_string.length,
mutable_string.buffer,
(unsigned long)inmutable_string.length,
inmutable_string.buffer);

return 0;
}
_________________________________________________________________

BTW, how are you handling this in your Better String Library? I see that you
have a function called `cstr2bstr()', but AFAICT it uses dynamic memory
allocation.

> "Efficiency and the standard library" is an
> oxymoron.  Compare this to the implementation in the Better String
> Library.

[...]

```
 0
no6 (2828)
2/15/2010 12:39:14 AM
```On Feb 15, 1:44=A0am, Seebs <usenet-nos...@seebs.net> wrote:
> On 2010-02-14, Richard Harter <c...@tiac.net> wrote:
>
> > On Sun, 14 Feb 2010 02:15:15 -0800 (PST),spinoza1111
> ><spinoza1...@yahoo.com> wrote:
> >> who is today unable, unlike me, to crank this level
> >> of code in the time I took...about two hours for the first
> >> version, and a total of 8..10 hours thereafter.
> > I certainly hope that I am never able to crank out that
> > level of code, regardless of the time it takes.
>
> And I certainly hope I never reach a point where a ten-minute project
> takes two hours to write and maybe 8-10 hours thereafter to produce an
> elaborate, complicated, inefficient, version which we still aren't totall=
y
> sure works.

But dear Peter, you haven't written a working solution to the problem
(replace() without string.h) in a week, nor have you given any
evidence of being able to do so. Quite the opposite, Mister Off By
One.

Part of the myth is that software is easy and a truly reusable and
efficient library routine such as this can be written by one magical
person in an hour: Kernighan contributes to this myth-making in the
O'Reilly anthology Beautiful Code with his story-telling about Rob
Pike writing a regex (which wasn't a real regex) by himself in an
hour.

The software that is written in five minutes or an hour is almost
always delivered with smartass remarks such as yours, such as "you'd
be better test it" or "I didn't actually check for %s", accompanied by
anti-intellectual and sexist remarks, generally to the effect that
anyone who worries about marginal conditions in the deliverer's code
isn't being "practical", is "academic", or a queer.

Real development can be done solitary but this takes even longer than
collaborative development of truly reusable routines, which takes time
owing to the need to coordinate people, here in different time zones,
and to get rid of disruptive individuals such as you.
>
> -s
> --
> Copyright 2010, all wrongs reversed. =A0Peter Seebach / usenet-nos...@see=
bs.nethttp://www.seebs.net/log/<-- lawsuits, religion, and funny picturesht=
tp://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!

```
 0
spinoza1111 (3246)
2/15/2010 3:28:07 AM
```On Feb 15, 1:30=A0am, c...@tiac.net (Richard Harter) wrote:
> On Sun, 14 Feb 2010 02:15:15 -0800 (PST),spinoza1111
>
>
>
> <spinoza1...@yahoo.com> wrote:
> >On Feb 14, 7:05=3DA0am, c...@tiac.net (Richard Harter) wrote:
> [snip]
>
> > At some point in the distant past, Harter, you were able to
> > write competent code, for I saw an old 1990 program of yours
> > that was competent. =A0I think you are now some sort of
> > manager
>
> Chortle. =A0Excuse me while I go whip some slaves, er,
>
> > who is today unable, unlike me, to crank this level
> > of code in the time I took...about two hours for the first
> > version, and a total of 8..10 hours thereafter.
>
> I certainly hope that I am never able to crank out that
> level of code, regardless of the time it takes.

I don't know what you mean. Do you mean you never hope to become as
truly competent as I am, since in programming (which is now a cost
center in which creative and intelligent people are now merely
disruptive) such great code merely attracts envy and infantile rage,
such as we see in Seebach?
>
> [snip]
>
>
>
> >> (10) Only one of strNew, strNewStart is needed.
>
> >You don't know what you're talking about, and you have not diligently
> >or adequately studied the code. =A0strNew is needed to index through the
> >new string, whereas we need to return strNewStart.
>
> You are right. =A0Mea culpa.

Fine. Please study the code before emitting judgements next time.
>
>
>
> >"Never defined Index variables" is gibberish.
>
> Well, no, it's not. =A0In the C standard "defined" has a very
> specific, parochial meaning. =A0 More generally, however, the
> definition of a variable is a description of its usage in the
> code. =A0A comprehensive definition includes such things as the
> invariants and constraints associated with the variable, and the
> kind of things it represents.
>
> There seldom is a need for elaborate definitions. =A0Often none is
> wanted. =A0Often, however, the presence of an explicit definition
> makes a lot of difference, both in reading the code and writing.
> The absence of explicit definitions can lead to nasty, obscure
> bugs.

I think what's best, then, would be to rename them retaining my great
pre-Syzmonyi Hungarian and index followed by a trailer as in
ptrIndex3match.
>
> It occurs to me that you did not recognize "Index variables" as
> shorthand for the variables named ptrIndex0, etc. =A0If that is
> what you were on about, that was what was meant.

But: you recognized them as index variables.

Bear in mind one simple fact. Nobody else in this thread has been able
to solve the assigned problem. I do not think that this is because
nobody else is able to! "Writing a replace() without using string.h in
some reasonably efficient way" is nothing more than a basic university
assignment.

I think instead that owing to the domination of these threads by thugs
and twerps like Heathfield and Seebach, most posters are afraid to,
since any code, in any style, at any level of quality, will be mocked
by people who themselves are not very competent, such as Heathfield,
who believed at least in 2000 that it's acceptable to shove arbitrary
data into the nodes of a linked list, or Mr. Off By One Seebach. The
mockery and falsehoods to which they would be exposed can threaten
their positions.

But since I am not employed as a programmer or in computing, nor seek
work in those fields, I decided to expose how these newsgroups are
being abused.

Rob Pike or any other great programmer could post here *incognito*,
and since great programmers almost always have idiomatic relationships
to code and markers of style, they would be flamed for those markers,
as well as for any and all bugs. I do not know of any great programmer
who also writes code free of bugs the first time: in fact, given
Knuth's free confession of the mistake he always makes when coding
binary search, I'd guess that great programmers are so fecund, with a
higher volume of output, that their code has a higher level of
bugs...which they, as great programmers, are far more eager to fix
than Peter Seebach was anxious to fix his famous %s bug.

```
 0
spinoza1111 (3246)
2/15/2010 3:45:58 AM
```On Feb 15, 7:33=A0am, websnarf <websn...@gmail.com> wrote:
> On Feb 10, 12:54=A0pm, Dann Corbit <dcor...@connx.com> wrote:
>
>
>
>
>
> > In article <slrnhn628c.o3u.usenet-nos...@guild.seebs.net>, usenet-
> > nos...@seebs.net says...
> > > This may have gotten buried given that it started in a Nilges thread,
> > > but it's actually pretty interesting.
>
> > > There was some discussion of algorithms to perform the task:
> > > =A0 =A0Inputs: =A0target string, replacement string, original string
> > > =A0 =A0Output: =A0a newly-allocated string containing the original
> > > =A0 =A0 =A0string with each copy of the target string replaced with t=
he
> > > =A0 =A0 =A0replacement string.
>
> > > Here's a hunk of mine:
>
> > > =A0 =A0 =A0 =A0 for (count =3D 0, t =3D strstr(target, in); t && *t; =
t =3D strstr(t, in)) {
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ++count;
> > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 t +=3D inlen;
> > > =A0 =A0 =A0 =A0 }
>
> Yeah fantastic -- because you are using C strings, you are forced to
> execute this in two passes, one to figure out how much space to
> allocation and the second to do the copies.
>
>
>
>
>
> > > Here's a hunk of another one:
>
> > > > =A0 =A0 ptrIndex1 =3D strMaster;
> > > > =A0 =A0 while(*ptrIndex1)
> > > > =A0 =A0 {
> > > > =A0 =A0 =A0 =A0 ptrIndex0 =3D ptrIndex1;
> > > > =A0 =A0 =A0 =A0 while (-1)
> > > > =A0 =A0 =A0 =A0 {
> > > > =A0 =A0 =A0 =A0 =A0 =A0 for(;
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex1 && *ptrIndex1 !=3D *strT=
arget;
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ptrIndex1++);
> > > > =A0 =A0 =A0 =A0 =A0 =A0 for(ptrIndex2 =3D strTarget, ptrIndex3 =3D =
ptrIndex1;
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex3
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 &&
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex2
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 &&
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *ptrIndex3 =3D=3D *ptrIndex2;
> > > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ptrIndex3++, ptrIndex2++);
> > > > =A0 =A0 =A0 =A0 =A0 =A0 if (!*ptrIndex2) break;
> > > > =A0 =A0 =A0 =A0 =A0 =A0 ptrIndex1 =3D ptrIndex3;
> > > > =A0 =A0 =A0 =A0 =A0 =A0 if (!*ptrIndex3) break;
> > > > =A0 =A0 =A0 =A0 }
>
> > > These hunks are essentially performing the same part of the core loop=
;
> > > find the next occurrence of the target string in the original string.
>
> > > The second one was written by Edward Nilges ("spinoza1111"). =A0He of=
fers
> > > in its defense the assertion that it's the "best" algorithm. =A0(Neve=
rmind
> > > that it's got a bug; the bug could be fixed easily.)
>
> > > My thinking:
>
> > > The first is better, not because it's less buggy (that could be fixed=
), but
>
> Both are using C strings and suffer from the stupidity of not being
> able to use lengths to accelerate the performance of any portion of
> this algorithm. =A0"Efficiency and the standard library" is an
> oxymoron. =A0Compare this to the implementation in the Better String
> Library.
>
> > For a standard library, the *most* important thing is correctness.
>
> How can one implement gets() correctly?
>
> > [...]=A0IOW, a bsearch() function that is blazing fast but fails if the=
re are
> > more than 2 billion items is not as good as one that is only half as fa=
st
> > but works with anything up to size_t (-1) number of elements.
>
> > Assuming correctness, then efficiency should be the next decider.
>
> And what if the specification of the C library does not allow the
> algorithm to be implemented efficiently?
>
> > [...]=A0An
> > interesting project would be to take a collection of all public C
> > libraries and do the following:
> > 1. Exhaustively test for correctness
>
> How would you test gets() for correctness.
>
> The Better String Library, on the other hand *COMES WITH* a unit test
> that does a reasonable amount of testing. =A0*Correctness* is also a
> more usefully defined concept in the Better String Library (every
> function must support all possible parametric inputs so long as each
> of the contents of the parameters are independently valid with respect
> to their own type.)
>
> If the ANSI C language committee were forced to ship a unit test for
> the C standard library, it would probably be a very different
> language.
>
> > 2. Analyze for efficiency
>
> Even if it doesn't make any sense to do so? =A0qsort(), for example, is
> *NEVER* efficient in any circumstance. =A0Nearly the full complement of
> string functions are easily beat by the portable "Better String
> Library" implementation (note that the latest hand optimized x86
> assembly language libraries for the Intel/Microsoft have managed to
> catch up to the Better String Library in a few cases, but only by
> using esoteric instructions.)
>
> > 3. Choose best of breed from the above analysis. =A0It could also be a
> > hybrid (e.g. a decider function chooses the best algorithm based on
> > conditions).
>
> If the libraries are written in assembly language (which in Intel and
> Microsoft's case is true) does that make sense in your comparison?
> You could only say that a library was good on a particular platform.
>
> --
> Paul Hsiehhttp://www.pobox.com/~qed/http://bstring.sf.net/

Is the Better String Library based on a linked list representation of
strings?
```
 0
spinoza1111 (3246)
2/15/2010 3:48:40 AM
```"spinoza1111" <spinoza1111@yahoo.com> wrote in message
On Feb 15, 7:33 am, websnarf <websn...@gmail.com> wrote:

[...]

> > Both are using C strings and suffer from the stupidity of not being
> > able to use lengths to accelerate the performance of any portion of
> > this algorithm. "Efficiency and the standard library" is an
> > oxymoron. Compare this to the implementation in the Better String
> > Library.

[...]

> Is the Better String Library based on a linked list representation of
> strings?

I don't think so. BTW, have you taken a look at this:

```
 0
no6 (2828)
2/15/2010 4:16:33 AM
```On Feb 15, 5:28=A0am, spinoza1111 <spinoza1...@yahoo.com> wrote:
> Part of the myth is that software is easy and a truly reusable and
> efficient library routine such as this can be written by one magical
> person in an hour: Kernighan contributes to this myth-making in the
> O'Reilly anthology Beautiful Code with his story-telling about Rob
> Pike writing a regex (which wasn't a real regex) by himself in an
> hour.
>
As I told my students, don't confuse doing the planning with the time
it takes to write down the plan.

Once you've decided on the specifications and behaviour of a string
library, writing the code should be trivial - almost certainly all you
will be doing is copying, concatenation, and a few simple searches.
However getting the specifications right is hard.
```
 0
2/15/2010 6:44:28 AM
```On 13 Feb, 10:43, Tim Streater <timstrea...@waitrose.com> wrote:
> On 13/02/2010 10:30, spinoza1111 wrote:

> > My code is hard to read, it is said (on dit). In a sense, it is. I
> > find it hard to read at times myself.
>
> Then it's shitty code, pure and simple.

if was hard to write then it should be hard to understand

:-)
```
 0
2/15/2010 9:17:36 AM
```On 13 Feb, 11:22, Richard Heathfield <r...@see.sig.invalid> wrote:
> spinoza1111 wrote:

> > // Calculate string length
> > long strLength(char *strInstring)
> > {
> > =A0 =A0 char *ptrInstring;
> > =A0 =A0 for (ptrInstring =3D strInstring; *ptrInstring; ptrInstring++);
> > =A0 =A0 return ptrInstring - strInstring;
> > }
>
>
> long strLength(const char *s)
> {
> =A0 =A0long len =3D 0;
> =A0 =A0while(*s++) ++len;
> =A0 =A0return len;
>
> }

isn't strLength in the implementaion namespace?

<snip>
```
 0
2/15/2010 9:26:09 AM
```On Feb 14, 4:39=A0pm, "Chris M. Thomasson" <n...@spam.invalid> wrote:
> "websnarf" <websn...@gmail.com> wrote in message
> On Feb 10, 12:54 pm, Dann Corbit <dcor...@connx.com> wrote:
> > > In article <slrnhn628c.o3u.usenet-nos...@guild.seebs.net>, usenet-
> > > nos...@seebs.net says...
> > > > This may have gotten buried given that it started in a Nilges threa=
d,
> > > > but it's actually pretty interesting.
>
> > > > There was some discussion of algorithms to perform the task:
> > > > Inputs: target string, replacement string, original string
> > > > Output: a newly-allocated string containing the original
> > > > string with each copy of the target string replaced with the
> > > > replacement string.
>
> > > > Here's a hunk of mine:
>
> > > > for (count =3D 0, t =3D strstr(target, in); t && *t; t =3D strstr(t=
, in)) {
> > > > ++count;
> > > > t +=3D inlen;
> > > > }
> > Yeah fantastic -- because you are using C strings, you are forced to
> > execute this in two passes, one to figure out how much space to
> > allocation and the second to do the copies.
>
> Well, you are not necessarily "forced" to loop on `strstr()' in two phase=
s.
> One can cache the results such that a second round of `strstr()' calls ca=
n
> be completely eliminated. I created a crude little program that does this=
:
>
>
> This has to improve things a little bit...
>
> ;^)

Right, but then you are mixing line length delimiting with C strings.
And you are basically solving the problem from scratch rather than
using the semantics implied by the C library.

Of course the Better String Library has what you suggest above as an
obviously available technique since lengths are always available.

> > > > Here's a hunk of another one:
>
> [...]
>
> > Both are using C strings and suffer from the stupidity of not being
> > able to use lengths to accelerate the performance of any portion of
> > this algorithm.
>
> Humm... Of course one can use C strings in conjunction with a length.
> Perhaps something like this crap:
> _________________________________________________________________
> #include <stdio.h>
>
> struct string
> {
> =A0 =A0 size_t length;
> =A0 =A0 char* buffer;
>
> };
>
> #define STRING(mp_name, mp_len, mp_content) \
> =A0 =A0 char mp_name ## _temp mp_len =3D mp_content; \
> =A0 =A0 struct string mp_name =3D \
> =A0 =A0 { \
> =A0 =A0 =A0 =A0 sizeof(mp_name ## _temp) - 1, \
> =A0 =A0 =A0 =A0 mp_name ## _temp \
> =A0 =A0 }
>
> #define STRING_CONST_FROM_CSTR(mp_name, mp_str) \
> =A0 =A0 struct string const mp_name =3D \
> =A0 =A0 { \
> =A0 =A0 =A0 =A0 sizeof(mp_str) - 1, \
> =A0 =A0 =A0 =A0 mp_str \
> =A0 =A0 }
>
> int main()
> {
> =A0 =A0 STRING(mutable_string, [], "Hello World! (mutable)");
>
> =A0 =A0 STRING_CONST_FROM_CSTR(inmutable_string, "Hello World! (inmutable=
)");
>
> =A0 =A0 printf("mutable_string(%lu) =3D %s\n"
> =A0 =A0 =A0 =A0 =A0 =A0"inmutable_string(%lu) =3D %s\n",
> =A0 =A0 =A0 =A0 =A0 =A0(unsigned long)mutable_string.length,
> =A0 =A0 =A0 =A0 =A0 =A0mutable_string.buffer,
> =A0 =A0 =A0 =A0 =A0 =A0(unsigned long)inmutable_string.length,
> =A0 =A0 =A0 =A0 =A0 =A0inmutable_string.buffer);
>
> =A0 =A0 return 0;}
>
> _________________________________________________________________
>
> BTW, how are you handling this in your Better String Library? I see that =
you
> have a function called `cstr2bstr()', but AFAICT it uses dynamic memory
> allocation.

Look up the bsStatic() and bsStaticBlkParms() macros to see how I
handle that.

(Note that if you pass non-string literal values to your macros you
will get strange results.)

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/
```
 0
websnarf (1153)
2/15/2010 10:24:41 AM
```On Feb 15, 11:26=A0am, Nick Keighley <nick_keighley_nos...@hotmail.com>
wrote:
> On 13 Feb, 11:22, Richard Heathfield <r...@see.sig.invalid> wrote:
>
> isn't strLength in the implementaion namespace?
>
> <snip>- Hide quoted text -
>
>
So are things like strength, island, isobars, strip_spaces, today,
meme, delta_t.

Most compilers won't warn you by default and it is a complete nuisance
to remember.

```
 0
2/15/2010 10:24:42 AM
```On Feb 14, 8:16=A0pm, "Chris M. Thomasson" <n...@spam.invalid> wrote:
> On Feb 15, 7:33 am, websnarf <websn...@gmail.com> wrote:
> > > Both are using C strings and suffer from the stupidity of not being
> > > able to use lengths to accelerate the performance of any portion of
> > > this algorithm. "Efficiency and the standard library" is an
> > > oxymoron. Compare this to the implementation in the Better String
> > > Library.
>
> [...]
>
> > Is the Better String Library based on a linked list representation of
> > strings?

No it is based on exponential realloc() lengths for the backing
memory, and otherwise defining the string as length limited, not '\0'
limited.

> I don't think so. BTW, have you taken a look at this:
>
/spe986.pdf

Yes, Ropes -- as far as I understand it, they have never finished
implementing it.  The VStr library is probably the closest thing to it
that at least is fully implemented.  But IMHO, it trades off a lot of
complexity that you will end up paying for in practical cases in order
to achieve good results in atypical cases.

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/
```
 0
websnarf (1153)
2/15/2010 10:32:23 AM
```On 15/02/2010 09:17, Nick Keighley wrote:
> On 13 Feb, 10:43, Tim Streater<timstrea...@waitrose.com>  wrote:
>> On 13/02/2010 10:30, spinoza1111 wrote:
>
>>> My code is hard to read, it is said (on dit). In a sense, it is. I
>>> find it hard to read at times myself.
>>
>> Then it's shitty code, pure and simple.
>
> if was hard to write then it should be hard to understand

Yes, I've come across others with that view in the past (others besides
Spinny, that is). In one egregious instance the writer declined to do
any doccy for his code, for just the reason you cite. He was too
impressed by his own cleverness, the offering was "neat", to use his
words. Asked to write some code to take a text file and convert it to
another form, he'd written a "compiler", so instead of a small piece of
code to do the job, it was humongous - with the attendant issues of
maintainability and modifiability.

It was beneath his dignity, you see, to consider others, just as it's
beneath Spinny's dignity to consider others or to bother understanding
feof() or whatever it was. Well, fuck to the lot of them, is what I say.

--
Tim

"That the freedom of speech and debates or proceedings in Parliament
ought not to be impeached or questioned in any court or place out of
Parliament"

Bill of Rights 1689
```
 0
timstreater (945)
2/15/2010 10:42:02 AM
```In article <c95a3ee2-4548-4040-a3dc-27a8615ed517@d2g2000yqa.googlegroups.com>,
Nick Keighley  <nick_keighley_nospam@hotmail.com> wrote:
>isn't strLength in the implementaion namespace?

No.  "str" followed by a lowercase letter. (7.26.11)

-- Richard
--
Please remember to mention me / in tapes you leave behind.
```
 0
richard91 (3692)
2/15/2010 1:03:56 PM
```Tim Streater <timstreater@waitrose.com> writes:

> On 15/02/2010 09:17, Nick Keighley wrote:
>> On 13 Feb, 10:43, Tim Streater<timstrea...@waitrose.com>  wrote:
>>> On 13/02/2010 10:30, spinoza1111 wrote:
>>
>>>> My code is hard to read, it is said (on dit). In a sense, it is. I
>>>> find it hard to read at times myself.
>>>
>>> Then it's shitty code, pure and simple.
>>
>> if was hard to write then it should be hard to understand
>
> Yes, I've come across others with that view in the past (others besides
> Spinny, that is). In one egregious instance the writer declined to do
> any doccy for his code, for just the reason you cite. He was too
> impressed by his own cleverness, the offering was "neat", to use his
> words. Asked to write some code to take a text file and convert it to
> another form, he'd written a "compiler", so instead of a small piece of
> code to do the job, it was humongous - with the attendant issues of
> maintainability and modifiability.
>
> It was beneath his dignity, you see, to consider others, just as it's
> beneath Spinny's dignity to consider others or to bother understanding
> feof() or whatever it was. Well, fuck to the lot of them, is what I say.

Using these trivial example, there is no reason why the code could be
relatively clear. A lot of code can not be made so. Never write C for
the lowest denominator.

--
"Avoid hyperbole at all costs, its the most destructive argument on
the planet" - Mark McIntyre in comp.lang.c
```
 0
rgrdev_ (1097)
2/15/2010 1:48:06 PM
```On Feb 15, 6:42=A0pm, Tim Streater <timstrea...@waitrose.com> wrote:
> On 15/02/2010 09:17, Nick Keighley wrote:
>
> > On 13 Feb, 10:43, Tim Streater<timstrea...@waitrose.com> =A0wrote:
> >> On 13/02/2010 10:30,spinoza1111wrote:
>
> >>> My code is hard to read, it is said (on dit). In a sense, it is. I
> >>> find it hard to read at times myself.
>
> >> Then it's shitty code, pure and simple.
>
> > if was hard to write then it should be hard to understand
>
> Yes, I've come across others with that view in the past (others besides
> Spinny, that is). In one egregious instance the writer declined to do
> any doccy for his code, for just the reason you cite. He was too
> impressed by his own cleverness, the offering was "neat", to use his
> words. Asked to write some code to take a text file and convert it to
> another form, he'd written a "compiler", so instead of a small piece of
> code to do the job, it was humongous - with the attendant issues of
> maintainability and modifiability.

The anthropological lessons of these myths is "don't be too smart." Or
as we say in China, "the tallest stalk of rice is cut down".

This particular myth often appears both in break rooms in programming
"shops", and here. It is told in ceremonious whispers and is a post-
Enlightenment myth.

In it, "there used to be this guy who thought he was better than us",
and in it, he is whip't and scorn'd and driven away in humiliation.

His humiliation is of course what the tellers and hearers fear, and
the anthropological function is to assert membership in a tribe of
regular (Chomsky 3) guys who would never do what the Chosen One did in
the Dreamtime, such as write a compiler to solve a simple problem.

[Interesting solution, one which I recommend, but of course for only
"hard" problems with frequent requirements changes, in my book, "Build
Your Own .Net Language and Compiler" (Apress 2004). One I've in fact
used.]

In some cases in my (30 year) programming career, I've overrated the
intelligence and work ethic of my mates, and I may have unleashed some
surprises like the one you describe.

But: the point of mythologizing the story is "never, ever, do that,
lest you be exposed, lest what Adorno called the 'secret contour of
your weakness' be out there, you naked in the face of the raging mob
of programmers who have to maintain your crap".

The mythical admonition has the effect of making acceptable solutions
over-simplified with obvious bugs (such as Seebach's famous %s, and
percent bugger all, replacer which started this thread) that are in
many cases, even acknowledged by the developers with a self-satisfied
smirk, and no plan whatsoever to fix these "issues". Objections are

Certain types of problems, as your coworker may have known, are solved
less by a hard-coded solution than by a language for expressing the
set of possible solutions. This is in fact an old and useful problem
solver in the real world; in The Psychology of Computer Programming,
Gerald Weinberg describes the solution of a difficult problem of
properly configuring automobile features in the form of tables
constituting a language. However, it flies in the face of management's
search for the dumb and dumber solution.

Sure, the guy may have gone overboard. But the effect of the myth is
to bias programmers to a "simplicity" which permits them to make silly
mistakes.

"No use goin' on; de dam willains will keep a scougin' and slappin'
each
oder, Massa Stubb; dey don't hear one word; no use a-preaching to
such dam g'uttons as you call 'em, till dare bellies is full, and dare
bellies is bottomless; and when dey do get 'em full, dey wont hear you
den; for den dey sink in the sea, go fast to sleep on de coral, and
can't hear noting at all, no more, for eber and eber."

- Herman Melville, Moby Dick, or The Whale

>
> It was beneath his dignity, you see, to consider others, just as it's
> beneath Spinny's dignity to consider others or to bother understanding
> feof() or whatever it was. Well, fuck to the lot of them, is what I say.

Or whatever. Yes, I had to refresh my memory (you might also consider
doing your homework on what's what before posting: there's really no
excuse not to since so much information is online).

As I said, this is because intelligent people prefer learning and
remembering elegant things, and feof() is coyote ugly, and, as I said,
a bug waiting to happen when a C program has to do an extra read
merely to check EOF from a device.

Intelligent people also prefer the company of the enlightened, and
that's why they leave many programming jobs after the company passes
the point of no return, where innovation gives way to computing as a
cost center staffed by eunuchs.
>
> --
> Tim
>
> "That the freedom of speech and debates or proceedings in Parliament
> ought not to be impeached or questioned in any court or place out of
> Parliament"
>
> Bill of Rights 1689

```
 0
spinoza1111 (3246)
2/15/2010 2:24:07 PM
```On Feb 15, 6:32=A0pm, websnarf <websn...@gmail.com> wrote:
> On Feb 14, 8:16=A0pm, "Chris M. Thomasson" <n...@spam.invalid> wrote:
>
> > On Feb 15, 7:33 am, websnarf <websn...@gmail.com> wrote:
> > > > Both are using C strings and suffer from the stupidity of not being
> > > > able to use lengths to accelerate the performance of any portion of
> > > > this algorithm. "Efficiency and the standard library" is an
> > > > oxymoron. Compare this to the implementation in the Better String
> > > > Library.
>
> > [...]
>
> > > Is the Better String Library based on a linked list representation of
> > > strings?
>
> No it is based on exponential realloc() lengths for the backing
> memory, and otherwise defining the string as length limited, not '\0'
> limited.

Exponential? You mean you double each request? Sounds kind of like Las
Vegas to me. Might make sense.

Until very recently, I thought that bit length was an unacceptable
restriction on string length, but if one ponders the scale of long
long, it is more than enough.

However, for easy modification, I don't think a doubly linked list
representation of strings with a length code could be beat.

When I implemented something vaguely like this using long and not long
long in 1990, I discovered my concept of "inspect" which I later used
in OO code, for IF the string data structure contains a length and a
linked list, the total lengths of the list entries should never not
match the length code, UNLESS you allow the length code to be an
Unknown value (-1?) until its value is needed just-in-time.

It was hard to get my doubly linked list working, but I did. It would
have been nice to have a separate tool for linked lists. Richard
Heathfield appears to have published such a tool in 2000, in C
Unleashed, but as far as I can determine (see elsethread), the
Dickiemaster copies the actual values into the list. This would have
blown me to Kingdom Come. I THINK the Heathman wanted to avoid using
pointer to void (he is welcome to comment here).

However, preprocessor macro implementation of linked list would avoid
both copying entries and pointer to void. But it would be at that
point in which I would ask myself, like Ross Perot's running mate VAdm
Jim Stockdale in 1992, "Who am I? Why am I here? And why am I not
coding in C Sharp, or getting laid?"
>
> > I don't think so. BTW, have you taken a look at this:
>

Very nice. I pulled a copy a few months ago while researching string.H
replacement.
>
> Yes, Ropes -- as far as I understand it, they have never finished
> implementing it. =A0The VStr library is probably the closest thing to it
> that at least is fully implemented. =A0But IMHO, it trades off a lot of
> complexity that you will end up paying for in practical cases in order
> to achieve good results in atypical cases.

Pity.
>
> --
> Paul Hsiehhttp://www.pobox.com/~qed/http://bstring.sf.net/

```
 0
spinoza1111 (3246)
2/15/2010 2:40:05 PM
```Nick Keighley wrote:

<snip>

> isn't strLength in the implementaion namespace?

Yes and no!

str followed by a lower case letter is in the implementation namespace.
On those grounds, strLength doesn't qualify (yet). But now consider a
C90 implementation with a case-insensitive linker.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
```
 0
rjh (10791)
2/15/2010 2:45:37 PM
```On Feb 15, 2:44=A0pm, Malcolm McLean <malcolm.mcle...@btinternet.com>
wrote:
> On Feb 15, 5:28=A0am,spinoza1111<spinoza1...@yahoo.com> wrote:> Part of t=
he myth is that software is easy and a truly reusable and
> > efficient library routine such as this can be written by one magical
> > person in an hour: Kernighan contributes to this myth-making in the
> > O'Reilly anthology Beautiful Code with his story-telling about Rob
> > Pike writing a regex (which wasn't a real regex) by himself in an
> > hour.
>
> As I told my students, don't confuse doing the planning with the time
> it takes to write down the plan.
>
> Once you've decided on the specifications and behaviour of a string
> library, writing the code should be trivial - almost certainly all you
> will be doing is copying, concatenation, and a few simple searches.
> However getting the specifications right is hard.

Malcolm, hi. I don't agree with you at all. "Find all strings AND
replace them" is as we've seen two problems, and the specifications
may only seem precise. Remember the gotchas I mentioned? Right to left
as opposed to left to right? Overlapping strings?

Any specification will contain aporias because specifications are in
natural language. Sure, you could write the algorithm or even hard
code inside the spec, but then it's no longer a spec, is it?

Over thirty years, primarily but not exclusively in business data
processing, I saw again and again the bad consequences of expanding
spec time and contracting code time, despite the fact that to do this
is conventional wisdom. Sure, if the Specifiers were Platonic
Guardians (Plato's philosopher kings who are implicitly knowledgeable
about the trades of the Artisans and themselves Warriors as well as
Guardians, and as virtuous as Boy Scouts on salt petre) then they
would know exactly what the "mere coders", the scribes, the slaves
needed.

There are two objections to this applied Platonism (apart from the
fact that Plato's sole value was starting a dialogue with posterity in
which the first response was a Bronx cheer from his star student
Aristotle).

The first is that if the specification is perfect we could merely
write a specification compiler and compile it, or, if labor is cheap
or as in a slave society free, we could merely tell the programmers to
mindlessly "code the spec". Or die.

If the specification is in any way imperfect, however, the slaves have
to bring this to the attention, whether directly or indirectly to the
Guardians. Of course, in this ideal state, one of absolute Perfection
and top-down authority, any Slave would have to be nucking futz to do
this. No, instead, he will quietly code the right way (or the wrong
way), trying to repair the spec rather than get his nuts chopped off
for being uppity.

But since, as I've demonstrated using Socrates' own dialectical form
of argument, the Platonic vision of perfect specs and mindless code is
utterly unsustainable malarkey, what really obtains in the real world?

It ain't pretty. Using the rhetoric, that "we mustn't code too early",
the favored or senior "analysts" buy themselves several months or even
years of "requirements analysis". During these happy times, they go to
a lot of meetings, talk in a lot of circles, write a lot of unreadable
and indeed unread documents, and do a lot of Facebooking and Youtubing
on the sly.

When Coding day finally dawns, a couple of hapless junior people,
often the ladies, along with a few misfits hired as "consultants", are
handed beautiful "requirements documents" filled with malarkey, tripe,
horse feathers, buggery, sodomy, clap trap, logical contradictions,

When they are unable, often through a form of low level Lutheran ich
kann nicht anders intellectual integrity, to code anything that runs
without catching fire using the clap trap and Higher Sodomy given unto
them from On High, they are said to be "incompetent programmers" and
are shown the door. The analysts then are given megabucks to retain a
Triad or Mafia dominated consulting firm, in many cases more than
once, and finally some rough beast of a System slouches towards
Bethlehem to be born, and to start misrouting trucks, losing baggage,
stopping pacemakers, and debiting the accounts of the wretched of the
earth.

you something by 5:00 EACH DAY that does something and then I go home,
you dig? I work side by side with a copilot, or as his copilot. I
bathe regularly so he don't throw up.
```
 0
spinoza1111 (3246)
2/15/2010 3:04:31 PM
```In article <p7-dnQHUq6aMw-TWnZ2dnUVZ7ohi4p2d@bt.com>,
Richard Heathfield  <rjh@see.sig.invalid> wrote:

>> isn't strLength in the implementaion namespace?

>Yes and no!
>
>str followed by a lower case letter is in the implementation namespace.
>On those grounds, strLength doesn't qualify (yet). But now consider a
>C90 implementation with a case-insensitive linker.

str* is not reserved for the implementation, but for future
standardisation.  Since C90 is distinctly not a future implementation,
it should not use it.

(I can see counter-arguments looking.)

-- Richard
--
Please remember to mention me / in tapes you leave behind.
```
 0
richard91 (3692)
2/15/2010 4:09:07 PM
```On Feb 15, 1:44=A0am, Seebs <usenet-nos...@seebs.net> wrote:
> On 2010-02-14, Richard Harter <c...@tiac.net> wrote:
>
> > On Sun, 14 Feb 2010 02:15:15 -0800 (PST),spinoza1111
> ><spinoza1...@yahoo.com> wrote:
> >> who is today unable, unlike me, to crank this level
> >> of code in the time I took...about two hours for the first
> >> version, and a total of 8..10 hours thereafter.
> > I certainly hope that I am never able to crank out that
> > level of code, regardless of the time it takes.
>
> And I certainly hope I never reach a point where a ten-minute project
> takes two hours to write and maybe 8-10 hours thereafter to produce an
> elaborate, complicated, inefficient, version which we still aren't totall=
y
> sure works.

Well, dear boy...

We're pretty sure that:

(1) Your off by one strlen didn't work. I guess I should say that it
is a minor saving grace of yours that the code was so simple that the
bug was easy to find, and I mean this in all sincerity.

It may be that my long and Meaningful names may in certain cases
conceal bugs from a raw statistical perspective. The fewer men, the
greater share of honor, said Henry V at Agincourt: the fewer
characters, the fewer places for bugs to hide. Based on this I may
reduce, somewhat, the length of the names I used.

(2) Your %s replacer didn't work. Here, another *mitzvot*, another
grace note, was that you told us about the bug. But in cases (1) and
(2) you proved that under the standards you subject others including
Schildt, you are not very competent. In (1), you made a basic mistake,
not a mistake of style or standards. In (2) you refused to fix the bug
you reported.

(2) You've taken a whole week as of yesterday by my clock not to even
try to solve the problem, which was to do replace() without string.h,
therefore the minimum amount of time you apparently need is w+x where
w=3Done week to not do anything and x is completely unknown. It's too
late to redeem yourself on this problem, since we can't be sure you
won't plagiarize me.

Now, as to assurance that my program works, as best we can tell.

We can see from a good English or other natural-language description
of the algorithm used that the algorithm works. Here is a good
description of the algorithm in English:

replace(master, target, replacement)

assert that target is not of zero length [there is no need to check
for NULL masters, targets or replacements in this step]
clear a linked list (set its header to null). Each node shall contain
the starting index and length of a "prefix" in the master, where a
"prefix" is the material to the left of a target occurrence or the end
of the string, along of course with the link. Note that a "prefix" can
be of zero length when two targets are adjacent.

from left to right, find all non-overlapping occurrences of the
target. When each occurrence is found, add the starting index and the
length of its "prefix" to the linked list UNLESS (1) there is at least
one member of the linked list, AND (2) this member records the
occurrence of one or more prefixes of zero length between adjacent
targets using a method to be chosen by the mere coder, as long as that
method records the number of prefixes of zero length. If (1) and (2)
obtain, increment the count of zero length prefixes. While scanning
left to right, sum-total the lengths of all prefixes, and each
occurrence of the target, in X.

in the above, add a linked list member for the "prefix" which appears
between the rightmost target and the end of the string only when this
prefix is not null.

in the above keep the index used to match the target character by
character for you shall need its value below.

allocate X bytes of storage [since we assume we shall use C]

concatenate all members of the linked list to the mallocated storage
by walking it: for each member append the prefix in it and then append
the replacement string if, and only if you are either not at the last
member or the last match of the target succeeded, indicating that the
master ends in a target. Note that all you need to do is have the last
value of the index used in the target to match: if this points at NUL
then the master ends with a target.

Now, from this algorithm statement a junior programmer (such as you,
Peter) can verify that the C code works in a half an hour, IF he can
parse reasonably complex English sentences.

Which brings up in fact a very, very interesting consideration.

It is that the common programmer reaction to The Code of the Other,
one of Shock and Awe, may in fact be the same psychological event as
the common reaction of many numerate but aliterate people to English
prose of a certain level of complexity.

The above algorithm description may be as "hard to read" as my code,
and it is certainly almost impossible for 90% percent of actual
programmers to write...despite the fact that interacting with texts of
this nature is an excellent way of writing software. This is something
Dijkstra knew, although he would strongly disagree with my belief that
the "informal" use of the above species of English could replace
mathematical formalism in practice.

But the "unreadability" of the above algorithm is not due to
verbosity. It is a social phenomenon in US and other "developed"
societies because (as many English professors will tell you) the
ability to write a sentence above a small upper bound of nesting and
complexity has been in a frighteningly rapid decline, tracking the
ability to read a coherent sentence above a small UB.

We see evidence for this here in the charges of "verbosity" when they
mean "I have a Master's degree,"

"I have a Master's degree" - Ask Mister Science, Duck's Breath Mystery
Theater

"...but I don't understand this".

Recall the passage from Dijkstra that I quoted earlier:

"Oh yes. In Europe a much larger fraction of the population CAN WRITE.
People in America have really suffered from the combination of TV,
which makes reading superfluous, and the telephone. A few years ago I
was at CalTech and that is a hiqh quality place and everybody
recommends it because the students are so bright. A graduate confessed
to me=97no he did not confess, he just stated it, that he did not care
about his writing, since he was preparing himself for an industrial
career. Poor industry!" - EWD 1985, cf
http://www.cs.utexas.edu/users/EWD/misc/vanVlissingenInterview.html

That is, the fact that many people self-select or are tracked towards
programming careers because of difficulties with reading & writing
such as dyslexia may explain their difficulties with maintenance
programming (the need to connect with the Code, that is the Text, of
the Other) and in coding above small lower bounds of complexity. They
may in fact not be able to formulate what it is they are doing in
English.

But: this model doesn't explain why Peter Seebach in fact seems to
write rather well, and has published a programming book. It may be
that there is a writing facility that "flies under the radar" in the
sense that the individual in question has learned how to write
effectively in a SIMPLE style, at the cost of ignoring complexity.

But this "flat" writing style tends to run out of oxygen at higher
levels, as witness the real rage of formally well-educated and
financially successful people with post-baccalaureate degrees at the
texts they were expected to master in graduate school. I've met more
than one English MA working in industry in various capacities who've
mentioned that they specialized in Milton, but in response to my
hostility that they really, really HATE fucking Milton, having had to
analyze Milton's famously complex grammar. They were in my opinion
unprepared by more basic English classes where the Little Darlings of
post-Sixties schools were spared the sentence diagrams we had to do,
and which I teach today.

Note that to adequately describe the replace algorithm above, I have
to fly above the upper bound of complexity found in most texts
(newspaper articles, emails, and popular novels) today OF NECESSITY.

What this means is that "complex code" is NOT the problem. My coding
tics, such as my pre-Szymonyi Hungarian, can be rapidly modified using
a good editor, and the underlying code will STILL present to many here
as "too complex", not because I'm a monstrum horrendum or a terrible
programmer, but because industrial society parks people in little
boxes labeled "numbers person" or "words person".

One more remark about the above natural language algorithm. In terms
of the pornographic and sado-masochistic division of labor
("specifications" versus "coding") it is neither fish nor fowl, and
this is as it should be. This is because a good programmer is a good
specifier and vice-versa, and a minimally acceptable programmer can
WRITE NATURAL LANGUAGE. Extreme Programming hasta la victoria siempre!

>
> -s
> --
> Copyright 2010, all wrongs reversed. =A0Peter Seebach / usenet-nos...@see=
bs.nethttp://www.seebs.net/log/<-- lawsuits, religion, and funny picturesht=
tp://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
```
 0
spinoza1111 (3246)
2/15/2010 4:17:53 PM
```On 15/02/2010 14:24, spinoza1111 wrote:
> On Feb 15, 6:42 pm, Tim Streater<timstrea...@waitrose.com>  wrote:
>> On 15/02/2010 09:17, Nick Keighley wrote:
>>
>>> On 13 Feb, 10:43, Tim Streater<timstrea...@waitrose.com>    wrote:
>>>> On 13/02/2010 10:30,spinoza1111wrote:
>>
>>>>> My code is hard to read, it is said (on dit). In a sense, it is. I
>>>>> find it hard to read at times myself.
>>
>>>> Then it's shitty code, pure and simple.
>>
>>> if was hard to write then it should be hard to understand
>>
>> Yes, I've come across others with that view in the past (others besides
>> Spinny, that is). In one egregious instance the writer declined to do
>> any doccy for his code, for just the reason you cite. He was too
>> impressed by his own cleverness, the offering was "neat", to use his
>> words. Asked to write some code to take a text file and convert it to
>> another form, he'd written a "compiler", so instead of a small piece of
>> code to do the job, it was humongous - with the attendant issues of
>> maintainability and modifiability.
>
> The anthropological lessons of these myths is "don't be too smart." Or
> as we say in China, "the tallest stalk of rice is cut down".

Which myth is that then? I'm dealing with reality - that of being left
with an undocumented mess to look after, because the clown in question
preferred to do something "cool" and "neat", rather than what he was
paid to do.

By the way, I don't object to his doing something "cool" and "neat", but
on his own time, OK?

[irrelevant drivel deleted]

> Sure, the guy may have gone overboard. But the effect of the myth is
> to bias programmers to a "simplicity" which permits them to make silly
> mistakes.

Way overboard in this instance. And which mistakes might those be, then?

>> It was beneath his dignity, you see, to consider others, just as it's
>> beneath Spinny's dignity to consider others or to bother understanding
>> feof() or whatever it was. Well, fuck to the lot of them, is what I say.
>
> Or whatever. Yes, I had to refresh my memory (you might also consider
> doing your homework on what's what before posting: there's really no
> excuse not to since so much information is online).

Which homework's that then, Spinny? There was nothing I needed to look up.

> As I said, this is because intelligent people prefer learning and
> remembering elegant things,

Very likely.

> and feof() is coyote ugly, and, as I said, a bug waiting to happen
> when a C program has to do an extra read merely to check EOF from
> a device.

Well, gee, life's a bitch sometimes, ain't it though! I'll let the good
people of Haiti know that while they might think *they* have problems,
poor Spinny has to deal with feof().

--
Tim

"That the freedom of speech and debates or proceedings in Parliament
ought not to be impeached or questioned in any court or place out of
Parliament"

Bill of Rights 1689
```
 0
timstreater (945)
2/15/2010 4:21:01 PM
```On Feb 15, 9:48=A0pm, Richard <rgrd...@gmail.com> wrote:
> Tim Streater <timstrea...@waitrose.com> writes:
> > On 15/02/2010 09:17, Nick Keighley wrote:
> >> On 13 Feb, 10:43, Tim Streater<timstrea...@waitrose.com> =A0wrote:
> >>> On 13/02/2010 10:30,spinoza1111wrote:
>
> >>>> My code is hard to read, it is said (on dit). In a sense, it is. I
> >>>> find it hard to read at times myself.
>
> >>> Then it's shitty code, pure and simple.
>
> >> if was hard to write then it should be hard to understand
>
> > Yes, I've come across others with that view in the past (others besides
> > Spinny, that is). In one egregious instance the writer declined to do
> > any doccy for his code, for just the reason you cite. He was too
> > impressed by his own cleverness, the offering was "neat", to use his
> > words. Asked to write some code to take a text file and convert it to
> > another form, he'd written a "compiler", so instead of a small piece of
> > code to do the job, it was humongous - with the attendant issues of
> > maintainability and modifiability.
>
> > It was beneath his dignity, you see, to consider others, just as it's
> > beneath Spinny's dignity to consider others or to bother understanding
> > feof() or whatever it was. Well, fuck to the lot of them, is what I say=
..
>
> Using these trivial example, there is no reason why the code could be
> relatively clear. A lot of code can not be made so. Never write C for
> the lowest denominator.

In more than one sense of the word, fella:

"Give not that which is holy unto the dogs, neither cast ye your
pearls before swine, lest they trample them under their feet, and turn
again and rend you." - Matthew 7.6

I'm not a Christian, but Jesus sure knew what he was talking about in
the Sermon on the Mount. Here, I am putting messages into bottles for
lurkers and the occasional person who can understand me. Oh, sure, I'm
trying to defeat Seebach, but fair and square; unlike Christ and like
Krishna, I believe we must fight the battle of life. As to Heathfield,
in this discussion, the guy's been nothing more than comic relief.

>
> --
> "Avoid hyperbole at all costs, its the most destructive argument on
> the planet" - Mark McIntyre in comp.lang.c

```
 0
spinoza1111 (3246)
2/15/2010 4:23:34 PM
```On Feb 15, 9:40=A0am, spinoza1111 <spinoza1...@yahoo.com> wrote:
>
> However, for easy modification, I don't think a doubly linked list
> representation of strings with a length code could be beat.

cache performance. And depending on how the list is implemented, many
programmers (even in C#) would likely balk at the extra overhead of
storing and following links for a "mere" string.

> copies the actual values into the list. This would have
> blown me to Kingdom Come.

Can you elaborate on this? I'm not sure I fully understand what you
mean.
```
 0
2/15/2010 4:30:35 PM
```On Feb 15, 6:30=A0pm, Julienne Walker <happyfro...@hotmail.com> wrote:
> On Feb 15, 9:40=A0am, spinoza1111 <spinoza1...@yahoo.com> wrote:
>
> Indeed. Too bad linked data structures have a tendency toward poor
> cache performance. And depending on how the list is implemented, many
> programmers (even in C#) would likely balk at the extra overhead of
> storing and following links for a "mere" string.
>
The main concern is, is this library easy to use? Only when the
program hits the treacle do ypu stary worrying about how efficient the
code is behind those nice interfaces.
For the sorts of programs I write, string handling is never the issue.
However that might change - I've got a new job looking at DNA
sequences.

```
 0
2/15/2010 4:49:40 PM
```On 2010-02-15, Malcolm McLean <malcolm.mclean5@btinternet.com> wrote:
> The main concern is, is this library easy to use? Only when the
> program hits the treacle do ypu stary worrying about how efficient the
> code is behind those nice interfaces.

Yeah.  My string library (like most C programmers, I wrote one at one point)
actually does have, under some circumstances, linked lists in it.  It never
seems to have become an issue.

They're used to provide familiar semantics.  Consider:
char s[256] = "hello, world!";
char *t;

t = strstr(s, "world");
strcpy(t, "sailor!");

You would expect this to leave s = "hello, sailor!" (note that it's a [], not
a *, and sized to provide enough room).

If you are doing structures, rather than raw pointers to characters, you
need some way to indicate that the same change must be made in both t and s.
My solution was to have s contain a linked list of strings derived from it,
and t contain a pointer to the string it is derived from.  When you modify
t, it observes that it is a substring of another string, so in fact, the
modification is passed back up to s.  Since t and s share storage, this
works.

-s
--
Copyright 2010, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
```
 0
usenet-nospam (2309)
2/15/2010 5:05:01 PM
```On Feb 15, 11:49=A0am, Malcolm McLean <malcolm.mcle...@btinternet.com>
wrote:
> On Feb 15, 6:30=A0pm, Julienne Walker <happyfro...@hotmail.com> wrote:> O=
n Feb 15, 9:40=A0am, spinoza1111 <spinoza1...@yahoo.com> wrote:
>
> > Indeed. Too bad linked data structures have a tendency toward poor
> > cache performance. And depending on how the list is implemented, many
> > programmers (even in C#) would likely balk at the extra overhead of
> > storing and following links for a "mere" string.
>
> The main concern is, is this library easy to use?

The two concerns aren't mutually exclusive. You can design an easy to
use interface *and* consider basic efficiency in the implementation
without skimping on either.

> Only when the
> program hits the treacle do ypu stary worrying about how efficient the
> code is behind those nice interfaces.

It doesn't matter how nice an interface is if it's too bloated for
anyone to want to use it. ;-) Efficiency is especially important with
libraries as well as ease of use, because with libraries you're less
aware of how they'll be used.

> For the sorts of programs I write, string handling is never the issue.
> However that might change - I've got a new job looking at DNA
> sequences.

I tend not to use C for any serious string handling. The language and
standard library support is too weak, IMO.
```
 0
2/15/2010 5:12:09 PM
```"websnarf" <websnarf@gmail.com> wrote in message
On Feb 14, 4:39 pm, "Chris M. Thomasson" <n...@spam.invalid> wrote:
> > "websnarf" <websn...@gmail.com> wrote in message
> > On Feb 10, 12:54 pm, Dann Corbit <dcor...@connx.com> wrote:
> > > > In article <slrnhn628c.o3u.usenet-nos...@guild.seebs.net>, usenet-
> > > > nos...@seebs.net says...
> > > > > This may have gotten buried given that it started in a Nilges
> > > > > thread,
> > > > > but it's actually pretty interesting.
> >
> > > > > There was some discussion of algorithms to perform the task:
> > > > > Inputs: target string, replacement string, original string
> > > > > Output: a newly-allocated string containing the original
> > > > > string with each copy of the target string replaced with the
> > > > > replacement string.
> >
> > > > > Here's a hunk of mine:
> >
> > > > > for (count = 0, t = strstr(target, in); t && *t; t = strstr(t,
> > > > > in)) {
> > > > > ++count;
> > > > > t += inlen;
> > > > > }
> > > Yeah fantastic -- because you are using C strings, you are forced to
> > > execute this in two passes, one to figure out how much space to
> > > allocation and the second to do the copies.
> >
> > Well, you are not necessarily "forced" to loop on `strstr()' in two
> > phases.
> > One can cache the results such that a second round of `strstr()' calls
> > can
> > be completely eliminated. I created a crude little program that does
> > this:
> >
> >
> > This has to improve things a little bit...
> >
> > ;^)
>
> Right, but then you are mixing line length delimiting with C strings.
> And you are basically solving the problem from scratch rather than
> using the semantics implied by the C library.

Isn't programming in C all about solving problems from scratch? lol.

;^)

> Of course the Better String Library has what you suggest above as an
> obviously available technique since lengths are always available.

Nice. Thank you for creating it.

> > > > > Here's a hunk of another one:
> >
> > [...]
> >
> > > Both are using C strings and suffer from the stupidity of not being
> > > able to use lengths to accelerate the performance of any portion of
> > > this algorithm.
> >
> > Humm... Of course one can use C strings in conjunction with a length.
> > Perhaps something like this crap:
> > _________________________________________________________________
[...]
> > _________________________________________________________________
> >
> > BTW, how are you handling this in your Better String Library? I see that
> > you
> > have a function called `cstr2bstr()', but AFAICT it uses dynamic memory
> > allocation.
>
> Look up the bsStatic() and bsStaticBlkParms() macros to see how I
> handle that.

Ahh, thank you:
___________________________________________________________________
/* Static constant string initialization macro */
#define bsStaticMlen(q,m)   {(m), (int) sizeof(q)-1, (unsigned char *) ("" q
"")}
#if defined(_MSC_VER)
# define bsStatic(q)        bsStaticMlen(q,-32)
#endif
#ifndef bsStatic
# define bsStatic(q)        bsStaticMlen(q,-__LINE__)
#endif

/* Static constant block parameter pair */
#define bsStaticBlkParms(q) ((void *)("" q "")), ((int) sizeof(q)-1)
___________________________________________________________________

I have not examined the code in any detail yet but a negative value for
`tagbstring::mlen' seems to denote that the memory is immutable right?
However, I don't quite understand the `-__LINE__' bit. Interesting.

> (Note that if you pass non-string literal values to your macros you
> will get strange results.)

Well, I did call that chunk of code "crap"...   :^)

I wanted a way to construct a counted string instance that pointed to a
mutable string without resorting to dynamic memory allocation. How can I do

```
 0
no6 (2828)
2/15/2010 6:02:18 PM
```"spinoza1111" <spinoza1111@yahoo.com> wrote in message
[...]

> It was hard to get my doubly linked list working, but I did. It would
> have been nice to have a separate tool for linked lists. Richard
> Heathfield appears to have published such a tool in 2000, in C
> Unleashed, but as far as I can determine (see elsethread), the
> Dickiemaster copies the actual values into the list. This would have
> blown me to Kingdom Come. I THINK the Heathman wanted to avoid using
> pointer to void (he is welcome to comment here).

I don't know why Richard implemented a simple linked-list that way. I take
it he is not that fond of intrusive linked lists.

> However, preprocessor macro implementation of linked list would avoid
> both copying entries and pointer to void. But it would be at that
> point in which I would ask myself, like Ross Perot's running mate VAdm
> Jim Stockdale in 1992, "Who am I? Why am I here? And why am I not
> coding in C Sharp, or getting laid?"

What about intrusive data-structures that do not require any copying and/or
void pointers? I use them all the time.

```
 0
no6 (2828)
2/15/2010 6:57:11 PM
```"spinoza1111" <spinoza1111@yahoo.com> wrote in message
[...]

> We can see from a good English or other natural-language description
> of the algorithm used that the algorithm works. Here is a good
> description of the algorithm in English:

> replace(master, target, replacement)

> assert that target is not of zero length [there is no need to check
> for NULL masters, targets or replacements in this step]

Why exactly do you need to assert that `target' is not a zero length string?
I would assume that:

replace("", "", "Hello World!");

will spit out a string equal to "Hello World!". I would also assume that:

replace("Hello World!", "", "XXX");

would produce a string equal to "Hello World!".

This is the way I implemented my `replace()' function here:

http://clc.pastebin.com/f62504e4c

I personally do not see anything wrong with that behavior.

[...]

```
 0
no6 (2828)
2/15/2010 7:38:35 PM
```"spinoza1111" <spinoza1111@yahoo.com> wrote in message
On Feb 15, 2:44 pm, Malcolm McLean <malcolm.mcle...@btinternet.com>
wrote:
> On Feb 15, 5:28 am,spinoza1111<spinoza1...@yahoo.com> wrote:> Part of the
> myth is that software is easy and a truly reusable and
> > > efficient library routine such as this can be written by one magical
> > > person in an hour: Kernighan contributes to this myth-making in the
> > > O'Reilly anthology Beautiful Code with his story-telling about Rob
> > > Pike writing a regex (which wasn't a real regex) by himself in an
> > > hour.
> >
> > As I told my students, don't confuse doing the planning with the time
> > it takes to write down the plan.
> >
> > Once you've decided on the specifications and behaviour of a string
> > library, writing the code should be trivial - almost certainly all you
> > will be doing is copying, concatenation, and a few simple searches.
> > However getting the specifications right is hard.

> Malcolm, hi. I don't agree with you at all. "Find all strings AND
> replace them" is as we've seen two problems, and the specifications
> may only seem precise. Remember the gotchas I mentioned? Right to left
> as opposed to left to right? Overlapping strings?

If a specification of the `replace()' function mentioned that it only
operates on non-overlapping comparands, then the overlapping string gotcha
is eliminated.

If a specification of the `replace()' function mentioned that it scans for
the comparand in a strict left-to-right fashion, then the
left-to-right/right-to-left gotcha is eliminated.

If a specification of the `replace()' function mentioned both of the above
claims, then both of the "gotchas" are eliminated.

```
 0
no6 (2828)
2/15/2010 7:43:50 PM
```!Google!!: from wabsnarf
> > Yeah fantastic -- because you are using C strings, you are forced to
> > Both are using C strings and suffer from the stupidity of not being
> > able to use lengths to accelerate the performance of any portion of
> > this algorithm. =A0"Efficiency and the standard library" is an
> > oxymoron. =A0Compare this to the implementation in the Better String
> > Library.

> Is the Better String Library based on a linked list representation of
> strings?

I don't know, but AFAIK the IBM OCL (C++) String had three
buffers - this made realloc rarer, but complicated things
like (char*) <String object> or o.cstr().

Length counted strings are not 'the Better String Library':

on the one hand, they are very old: Pascal, Rexx, C++,... all have
them in one way or another!

on the other hand, I think, it was a (time- and hw-)based design
decision to use '\0'-terminated strings - that had  - and has -
look up sentinels in any algorithm book.

On the third hand: Nobody hinders you (or?) to create and use a
structured string type (with similar interfaces to the std clib).

I'm sure, almost everybody here has implemented and used one.
(Mine was StringBuffer - don't remember, where the name came from)

The problems/complexitity come naturally:
to avoid often realloc,
you have to maintain length & capacity;
to handle input char*, char[] and lib-alloced memory,
you have to remember, how to destroy them;
to make it more flexible for the user, you may choose
to let them define 'Class-' and 'Object-' constr & destr
etc.
And with complexity/ease of use, you have to choose your
timing test cases more carefully.

I'm not saying, it's not worthwile: there are a lot of places,
where an automagically expanding string is nice (f.e. parsing
MIME-headers  with their comment and line continuation complexity).

But, that's C: use it's language and lib features, where it's
appropriate and s.th. else elsewhere.

And (to all whom it may concern): end this polemic!
The C lang and lib have some historic ballast,
live with it or leave it.

Wolfgang

(This, of course doesn't mean, I won't use a better sort than
qsort (which in itself in most libs isn't single-alg any more)
and in this ng, there are lot of interesting libs offered
(Surprise: I'm more interested in trees, hash, crypt, networking
than in something, I've done myself).

```
 0
2/15/2010 7:50:43 PM
```Chris M. Thomasson wrote:
) Why exactly do you need to assert that `target' is not a zero length string?
) I would assume that:
)
)
) replace("", "", "Hello World!");
)
) will spit out a string equal to "Hello World!". I would also assume that:

Why would you assume that ?
Why not 'Hello World' twice ?  Why not the empty string ?

) replace("Hello World!", "", "XXX");
)
)
) would produce a string equal to "Hello World!".

This is counter to your assumption above.

) This is the way I implemented my `replace()' function here:
)
) http://clc.pastebin.com/f62504e4c
)
)
)
) I personally do not see anything wrong with that behavior.

I do.
The two mentioned behaviours above are not consistent with each other.
Why do you make a special case of the first two strings both being empty ?

For all values of <anything>:
replace("", "<anything>", "<something>") = ""
except when <anything> is <nothing>, because then suddenly:
replace("", "", "<something>") = "<something>"

And also:

For all values of <anything>:
replace("<anything>", "", "<something>") = "<anything>"
except when <anything> is <nothing, because then suddenly:
replace("", "", <something>") = "<something>"

That's illogical.

To me, even
replace("<anything>", "", "<something>") = "<anything>"
is an arbitrary choice.  And not a very logical one either.

It's like saying division by zero yields zero.

Looking at the limit case, it should be:
replace("<anything>", "", "<something>") = "<something> repeated to infinity"

But that would cause unwanted behaviour.

SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
```
 0
willem7123 (117)
2/15/2010 7:53:38 PM
```"Willem" <willem@snail.stack.nl> wrote in message
news:slrnhnj9i2.2238.willem@snail.stack.nl...
> Chris M. Thomasson wrote:
> ) Why exactly do you need to assert that `target' is not a zero length
> string?
> ) I would assume that:
> )
> )
> ) replace("", "", "Hello World!");
> )
> ) will spit out a string equal to "Hello World!". I would also assume
> that:
>
> Why would you assume that ?
> Why not 'Hello World' twice ?  Why not the empty string ?

Well, I was thinking that if the source string is empty, and the comparand
is empty, then there is a match, therefore, the exchange string should
replace the empty source string.

> ) replace("Hello World!", "", "XXX");
> )
> )
> ) would produce a string equal to "Hello World!".
>
> This is counter to your assumption above.

I am thinking that the source is not empty, and the comparand is empty so
there cannot possibly be a match.

> ) This is the way I implemented my `replace()' function here:
> )
> ) http://clc.pastebin.com/f62504e4c
> )
> )
> )
> ) I personally do not see anything wrong with that behavior.
>
> I do.
> The two mentioned behaviours above are not consistent with each other.
> Why do you make a special case of the first two strings both being empty ?

Because an empty source and an empty comparand match each other?

Humm... Perhaps my line of thinking on this matter is just way off somewhere
deep in the heart of moron land. Thanks for challenging me on it Willem! I
will think this over.

[...]

```
 0
no6 (2828)
2/15/2010 8:03:23 PM
```On 12 Feb, 19:53, spinoza1111 <spinoza1...@yahoo.com> wrote:
> Perhaps we really need a string finder and a replacer which would
> encapsulate left to right, right to left, and what to do on overlap.
>
> However, the traditional way to do this can be slow, since it involves
> creating a "table" of occurrences.
>
> But two independent processes, a source and a sink, would handle the
> problems nicely.

How so?
Your first cite is a design question -
which your second doesn't even scratches!

(I know, you're with me on this:
Rexx's changestr(needle, hay, newneedle) is an implementation -
of one choice)

Wolfgang
```
 0
2/15/2010 8:03:25 PM
```Chris M. Thomasson wrote:
) Because an empty source and an empty comparand match each other?
)
)
) Humm... Perhaps my line of thinking on this matter is just way off somewhere
) deep in the heart of moron land. Thanks for challenging me on it Willem! I
) will think this over.

Well, the thing is that the comparand is matched against substrings of the
source.  And the question then becomes: Is the empty string a substring of
all possible strings ?

I can see where you're coming from, but mathematically speaking, it's an
anomaly.  You probably had to special-case it in your code, and that's
usually a good indication that it is also a special case in the
specification.

PS: If you don't account for an empty comparand, then the result is the
replacement string repeated indefinitely.  Sort of like how division by
zero is often thought to yield infinity.

SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
```
 0
willem7123 (117)
2/15/2010 8:12:10 PM
```I@
"spinoza1111" <spinoza1111@yahoo.com> ha scritto nel messaggio

@Perhaps i don't understand all the written text i see ( i think it is 50%)
@but it seems to me not justly you speak against peaceful and
@what show very educated and helpful people: Keith

On Feb 14, 4:09 am, Keith Thompson <ks...@mib.org> wrote:
> Seebs <usenet-nos...@seebs.net> writes:
>
> [...]
>
> > That said, I do like the idiom
> > size_t lenstr(char *string) {
> > char *end = string;
> > while (*end++)
> > ;
> > return end - string;
> > }
>
> > Not that it's likely to make a noticeable difference. Or that it's likely
> > worth it when obviously the standard library one will be fine.
>
> Note that ``end - string'' yields a value of type ptrdiff_t, a signed
> type which very likely can't represent all values of type size_t.
>
> This is unlikely to be an issue in practice. On typical 32-bit
> systems, problems show up only for strings longer than 2 gigabytes,
> and even then the properties of 2's-complement arithmetic are likely
> to result in the correct answer anyway.
>
> But all this analysis, resulting in the conclusion that it will
> almost certainly work properly, becomes unnecessary if you just
> use strlen().
>
> --
> Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
> Nokia
> "We must do something. This is something. Therefore, we must do this."
> -- Antony Jay and Jonathan Lynn, "Yes Minister"

Kenny McCormack, thou should'st be here at this hour:
For Kiki is in finest Form, posting pompously and sour:
Exhibiting ersatz Learning, and utter Pedantry:
He concludes, after "all this analysis" that "almost certainly"
That "it" (Seebie's shit) will yeah right..."work properly".
But for "123" Seebie's code grinds out to the amazement of the Crowd
The number...the number...FOUR, to dismay that is loud.
Whilst we the putative Trolls do dance amidst burning Tyres
Laughing our hairy Asses off at the doom of Pedantry's pretentious
spires!

```
 0
io_x
2/15/2010 8:30:16 PM
```In article <%ohen.82897\$Fe4.9664@newsfe21.iad>,
Chris M. Thomasson <no@spam.invalid> wrote:

>Why exactly do you need to assert that `target' is not a zero length string?

....

>I would also assume that:
>
>replace("Hello World!", "", "XXX");
>
>would produce a string equal to "Hello World!".

There are an arbitrary number of instances of the empty string before
the first character, between each pair of characters, and after the
last character.  Even if it does only one replacement at each position
it will still produce

XXXHXXXeXXXlXXXlXXXoXXX XXXWXXXoXXXrXXXlXXXdXXX!XXX

(I didn't type that in, I type "Hello World!" and used the editor's
replace function with the arguments "" and "XXX".)

>I would assume that:
>
>replace("", "", "Hello World!");
>
>will spit out a string equal to "Hello World!".

That's reasonable, since it replaces lots of empty strings with
empty strings.

-- Richard
--
Please remember to mention me / in tapes you leave behind.
```
 0
richard91 (3692)
2/15/2010 11:38:44 PM
```Nick Keighley wrote:
> On 13 Feb, 10:43, Tim Streater <timstrea...@waitrose.com> wrote:
>> On 13/02/2010 10:30, spinoza1111 wrote:
>
>>> My code is hard to read, it is said (on dit). In a sense, it is. I
>>> find it hard to read at times myself.
>> Then it's shitty code, pure and simple.
>
> if was hard to write then it should be hard to understand
>
> :-)
If the compiler can read it that's good enough. :-)

--
Joe Wright
"If you rob Peter to pay Paul you can depend on the support of Paul."
```
 0
joewwright (1738)
2/16/2010 2:09:39 AM
```On Feb 16, 4:30=A0am, "io_x" <a...@b.c.invalid> wrote:
> I@
> "spinoza1111" <spinoza1...@yahoo.com> ha scritto nel messaggionews:546b7d=
>
> @Perhaps i don't understand all the written text i see ( i think it is 50=
%)
> @but it seems to me not justly you speak against peaceful and
> @what show very educated and helpful people: Keith

Because they assault people who criticise them, making unfounded
claims about competence in a public place. They don't know how to
conduct themselves collegially.

I agree that to detect their malice, one needs to read English at a
somewhat higher level. I regret we are not using a truly global
language. However, their malice is real and familiar to me from my own

>
> On Feb 14, 4:09 am, Keith Thompson <ks...@mib.org> wrote:
>
>
>
>
>
> > Seebs <usenet-nos...@seebs.net> writes:
>
> > [...]
>
> > > That said, I do like the idiom
> > > size_t lenstr(char *string) {
> > > char *end =3D string;
> > > while (*end++)
> > > ;
> > > return end - string;
> > > }
>
> > > Not that it's likely to make a noticeable difference. Or that it's li=
kely
> > > worth it when obviously the standard library one will be fine.
>
> > Note that ``end - string'' yields a value of type ptrdiff_t, a signed
> > type which very likely can't represent all values of type size_t.
>
> > This is unlikely to be an issue in practice. On typical 32-bit
> > systems, problems show up only for strings longer than 2 gigabytes,
> > and even then the properties of 2's-complement arithmetic are likely
> > to result in the correct answer anyway.
>
> > But all this analysis, resulting in the conclusion that it will
> > almost certainly work properly, becomes unnecessary if you just
> > use strlen().
>
> > --
> > Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~k=
st>
> > Nokia
> > "We must do something. This is something. Therefore, we must do this."
> > -- Antony Jay and Jonathan Lynn, "Yes Minister"
>
> Kenny McCormack, thou should'st be here at this hour:
> For Kiki is in finest Form, posting pompously and sour:
> Exhibiting ersatz Learning, and utter Pedantry:
> He concludes, after "all this analysis" that "almost certainly"
> That "it" (Seebie's shit) will yeah right..."work properly".
> But for "123" Seebie's code grinds out to the amazement of the Crowd
> The number...the number...FOUR, to dismay that is loud.
> Whilst we the putative Trolls do dance amidst burning Tyres
> Laughing our hairy Asses off at the doom of Pedantry's pretentious
> spires!

```
 0
spinoza1111 (3246)
2/16/2010 6:50:15 AM
```On Feb 16, 4:03=A0am, "wolfgang.riedel" <wolfgang.riede...@web.de>
wrote:
> On 12 Feb, 19:53,spinoza1111<spinoza1...@yahoo.com> wrote:
>
> > Perhaps we really need a string finder and a replacer which would
> > encapsulate left to right, right to left, and what to do on overlap.
>
> > However, the traditional way to do this can be slow, since it involves
> > creating a "table" of occurrences.
>
> > But two independent processes, a source and a sink, would handle the
> > problems nicely.
>
> How so?
> Your first cite is a design question -
> which your second doesn't even scratches!
>
> (I know, you're with me on this:
> =A0Rexx's changestr(needle, hay, newneedle) is an implementation -
> of one choice)

Sorry, haven't used rexx recently. Can you explain?
>
> Wolfgang

```
 0
spinoza1111 (3246)
2/16/2010 6:51:27 AM
```On Feb 16, 3:43=A0am, "James" <n...@spam.invalid> wrote:
> "spinoza1111" <spinoza1...@yahoo.com> wrote in message
>
> On Feb 15, 2:44 pm, Malcolm McLean <malcolm.mcle...@btinternet.com>
> wrote:
>
>
>
>
>
> > On Feb 15, 5:28 am,spinoza1111<spinoza1...@yahoo.com> wrote:> Part of t=
he
> > myth is that software is easy and a truly reusable and
> > > > efficient library routine such as this can be written by one magica=
l
> > > > person in an hour: Kernighan contributes to this myth-making in the
> > > > O'Reilly anthology Beautiful Code with his story-telling about Rob
> > > > Pike writing a regex (which wasn't a real regex) by himself in an
> > > > hour.
>
> > > As I told my students, don't confuse doing the planning with the time
> > > it takes to write down the plan.
>
> > > Once you've decided on the specifications and behaviour of a string
> > > library, writing the code should be trivial - almost certainly all yo=
u
> > > will be doing is copying, concatenation, and a few simple searches.
> > > However getting the specifications right is hard.
> > Malcolm, hi. I don't agree with you at all. "Find all strings AND
> > replace them" is as we've seen two problems, and the specifications
> > may only seem precise. Remember the gotchas I mentioned? Right to left
> > as opposed to left to right? Overlapping strings?
>
> If a specification of the `replace()' function mentioned that it only
> operates on non-overlapping comparands, then the overlapping string gotch=
a
> is eliminated.
>
> If a specification of the `replace()' function mentioned that it scans fo=
r
> the comparand in a strict left-to-right fashion, then the
> left-to-right/right-to-left gotcha is eliminated.
>
> If a specification of the `replace()' function mentioned both of the abov=
e
> claims, then both of the "gotchas" are eliminated.

I guess it did, but I never wrote a spec. Probably should have. Of
course, in the so-called real world, one can specify left to right and
no overlap, the user can sign off, and the code can still be wrong.
```
 0
spinoza1111 (3246)
2/16/2010 6:53:31 AM
```On Feb 16, 2:57=A0am, "Chris M. Thomasson" <n...@spam.invalid> wrote:
> "spinoza1111" <spinoza1...@yahoo.com> wrote in message
>
> [...]
>
> > It was hard to get my doubly linked list working, but I did. It would
> > have been nice to have a separate tool for linked lists. Richard
> > Heathfield appears to have published such a tool in 2000, in C
> > Unleashed, but as far as I can determine (see elsethread), the
> > Dickiemaster copies the actual values into the list. This would have
> > blown me to Kingdom Come. I THINK the Heathman wanted to avoid using
> > pointer to void (he is welcome to comment here).
>
> I don't know why Richard implemented a simple linked-list that way. I tak=
e
> it he is not that fond of intrusive linked lists.

But his solution IS intrusive, unless by "intrusive" you mean
something else.

A linked list of pointers (the right way) is only "intrusive" in that
it consists of a set of eyes looking at data.

trouble, since you're both looking at data and grabbing it. Eyes and
paws.
>
> > However, preprocessor macro implementation of linked list would avoid
> > both copying entries and pointer to void. But it would be at that
> > point in which I would ask myself, like Ross Perot's running mate VAdm
> > Jim Stockdale in 1992, "Who am I? Why am I here? And why am I not
> > coding in C Sharp, or getting laid?"
>
> What about intrusive data-structures that do not require any copying and/=
or
> void pointers? I use them all the time.

That was my idea...use a macro for strong typing.
```
 0
spinoza1111 (3246)
2/16/2010 6:56:29 AM
```On Feb 16, 1:05=A0am, Seebs <usenet-nos...@seebs.net> wrote:
> On 2010-02-15, Malcolm McLean <malcolm.mcle...@btinternet.com> wrote:
>
> > The main concern is, is this library easy to use? Only when the
> > program hits the treacle do ypu stary worrying about how efficient the
> > code is behind those nice interfaces.
>
> Yeah. =A0My string library (like most C programmers, I wrote one at one p=
oint)
> actually does have, under some circumstances, linked lists in it. =A0It n=
ever
> seems to have become an issue.
>
> They're used to provide familiar semantics. =A0Consider:
> =A0 =A0 =A0 =A0 char s[256] =3D "hello, world!";
> =A0 =A0 =A0 =A0 char *t;
>
> =A0 =A0 =A0 =A0 t =3D strstr(s, "world");
> =A0 =A0 =A0 =A0 strcpy(t, "sailor!");
>
> You would expect this to leave s =3D "hello, sailor!" (note that it's a [=
], not
> a *, and sized to provide enough room).

At this point, it doesn't seem that "your" string library is what we
need, since you have to do its mallocs or fixed allocations. A true
solution would instead encapsulate all memory management.

Your library allows its users to make crappy and irresponsible secret
decisions as to "how big" things can get, which programmers are
rarely, if ever, qualified to make.
>
> If you are doing structures, rather than raw pointers to characters, you
> need some way to indicate that the same change must be made in both t and=
s.
> My solution was to have s contain a linked list of strings derived from i=
t,
> and t contain a pointer to the string it is derived from. =A0When you mod=
ify
> t, it observes that it is a substring of another string, so in fact, the
> modification is passed back up to s. =A0Since t and s share storage, this
> works.

OK, your string library is something like a library of pointers
outside the library; a collection of maps. I did something like this
in a preliminary fashion in 1987, but found that it was too much
trouble. A string library needs ownership of the strings.

However, a full library MIGHT want to sponsor both "virtual" strings
(pointers to space the library has neither mallocated nor predefined)
and "actual" strings (where the library has done the memory
management).

>
> -s
> --
> Copyright 2010, all wrongs reversed. =A0Peter Seebach / usenet-nos...@see=
bs.nethttp://www.seebs.net/log/<-- lawsuits, religion, and funny picturesht=
tp://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!

```
 0
spinoza1111 (3246)
2/16/2010 7:06:41 AM
```On Feb 16, 12:30=A0am, Julienne Walker <happyfro...@hotmail.com> wrote:
> On Feb 15, 9:40=A0am,spinoza1111<spinoza1...@yahoo.com> wrote:
>
>
>
> > However, for easy modification, I don't think a doubly linked list
> > representation of strings with a length code could be beat.
>
> Indeed. Too bad linked data structures have a tendency toward poor
> cache performance. And depending on how the list is implemented, many
> programmers (even in C#) would likely balk at the extra overhead of
> storing and following links for a "mere" string.

psychological. Frankly, Julienne, I'm tired of the facility in which
ordinary garden-variety transform "the need to think" into "wasting
overhead" as if their brains =3D=3D their computer.

But I can see where linked data structures have a tendency toward poor
cache performance, the blocks not being adjacent. If this is a
consideration, malloc() a big block and then do memory allocation
yourself inside the big block.

>
> > copies the actual values into the list. This would have
> > blown me to Kingdom Come.
>
> Can you elaborate on this? I'm not sure I fully understand what you
> mean.

It appeared to me that Richard's "general purpose linked list" of 2000
copies the values of anything passed to it into nodes of the linked
list. But if I were (in a blue moon) to use his code to re-present
strings as linked list, then he'd copy unbounded amounts of data
inside his code.

For the same reason RISC designers refused to implement the "fancy"
instructions of the old DEC Vax, a library function needs IF POSSIBLE
to have a fixed upper bound on the time it will consume. If I am
correct about Richard's code, if I pass him a huge data structure, his
timings will blow up because he's copying my data. Whereas if he'd
done the job right, for each node I pass him, he would have taken
constant time to set four-byte values (essentially the node's data
pointer and the pointer to the next element).

It is not always possible for a library function to have such a fixed
upper bound. If it is a replace() or a strstr(), OF COURSE its time
will depend on a fact about the data.

But this dependency falls right out of the problem, it is a necessary
fact about the problem. Whereas Richard's copy-o-rama comes out of
left field and seems to me completely unnecessary. If your compiler
supports pointer to void, use it, I say, and be damned.

Every "textbook" linked list I can recall uses a pointer in the data
node when the data is non-trivial. I was shocked, *shocked* to find
Richard did not.

But it is true that C handles this poorly because "void pointer is not
a 'real' pointer". This fact, about the inadequacy of C, has been
transformed into barbaric knowledge by the C clerisy, where what is a
criticism is re-intoned in tones of holy dread.

The problem wasn't solved until C++ and the notion of generics.
Preprocessor macros can simulate the effect of generics but only
painfully.

As far as I'm concerned: as far as I can see
Richard Heathfield does not work tastefully:
If something is coyote ugly and unpleasant
He seems to me to regard it, as a Heaven-sent
Opportunity
To increase the great weight of the world's misery.

We see, with dread, we say, oh hist,
He's copying ANYTHING into each node
Oh what a weary thing that is, and what a weary road.

He seems to be the Puritan
Who makes us sad whenever he can.
```
 0
spinoza1111 (3246)
2/16/2010 7:28:30 AM
```On Feb 16, 12:21=A0am, Tim Streater <timstrea...@waitrose.com> wrote:
> On 15/02/2010 14:24,spinoza1111wrote:
>
>
>
>
>
> > On Feb 15, 6:42 pm, Tim Streater<timstrea...@waitrose.com> =A0wrote:
> >> On 15/02/2010 09:17, Nick Keighley wrote:
>
> >>> On 13 Feb, 10:43, Tim Streater<timstrea...@waitrose.com> =A0 =A0wrote=
:
> >>>> On 13/02/2010 10:30,spinoza1111wrote:
>
> >>>>> My code is hard to read, it is said (on dit). In a sense, it is. I
> >>>>> find it hard to read at times myself.
>
> >>>> Then it's shitty code, pure and simple.
>
> >>> if was hard to write then it should be hard to understand
>
> >> Yes, I've come across others with that view in the past (others beside=
s
> >> Spinny, that is). In one egregious instance the writer declined to do
> >> any doccy for his code, for just the reason you cite. He was too
> >> impressed by his own cleverness, the offering was "neat", to use his
> >> words. Asked to write some code to take a text file and convert it to
> >> another form, he'd written a "compiler", so instead of a small piece o=
f
> >> code to do the job, it was humongous - with the attendant issues of
> >> maintainability and modifiability.
>
> > The anthropological lessons of these myths is "don't be too smart." Or
> > as we say in China, "the tallest stalk of rice is cut down".
>
> Which myth is that then? I'm dealing with reality - that of being left
> with an undocumented mess to look after, because the clown in question
> preferred to do something "cool" and "neat", rather than what he was
> paid to do.

What was he paid to do? Something hot and sloppy?
>
> By the way, I don't object to his doing something "cool" and "neat", but
> on his own time, OK?

But on the job we must produce crap at speed?

>
> [irrelevant drivel deleted]
>
> > Sure, the guy may have gone overboard. But the effect of the myth is
> > to bias programmers to a "simplicity" which permits them to make silly
> > mistakes.
>
> Way overboard in this instance. And which mistakes might those be, then?
>
> >> It was beneath his dignity, you see, to consider others, just as it's
> >> beneath Spinny's dignity to consider others or to bother understanding
> >> feof() or whatever it was. Well, fuck to the lot of them, is what I sa=
y.
>
> > Or whatever. Yes, I had to refresh my memory (you might also consider
> > doing your homework on what's what before posting: there's really no
> > excuse not to since so much information is online).
>
> Which homework's that then, Spinny? There was nothing I needed to look up=
..
>
> > As I said, this is because intelligent people prefer learning and
> > remembering elegant things,
>
> Very likely.
>
> > and feof() is coyote ugly, and, as I said, a bug waiting to happen
>
> =A0> when a C program has to do an extra read merely to check EOF from
>
> > a device.
>
> Well, gee, life's a bitch sometimes, ain't it though! I'll let the good
> people of Haiti know that while they might think *they* have problems,
> poor Spinny has to deal with feof().

Haiti? OK, an old argument: don't complain about anything, you have no
right given "the weight of the world". The problem being that Haiti's
problems were CAUSED by US corporations in the same system in which
they don't give programmers, *as a matter of principle* enough time to
do a quality job.
>
> --
> Tim
>
> "That the freedom of speech and debates or proceedings in Parliament
> ought not to be impeached or questioned in any court or place out of
> Parliament"
>
> Bill of Rights 1689

```
 0
spinoza1111 (3246)
2/16/2010 7:32:14 AM
```On 15 Feb, 14:40, spinoza1111 <spinoza1...@yahoo.com> wrote:
> On Feb 15, 6:32=A0pm, websnarf <websn...@gmail.com> wrote:
> > On Feb 14, 8:16=A0pm, "Chris M. Thomasson" <n...@spam.invalid> wrote:
> > > On Feb 15, 7:33 am, websnarf <websn...@gmail.com> wrote:

> Until very recently, I thought that bit length was an unacceptable
> restriction on string length, but if one ponders the scale of long
> long, it is more than enough.

if you mean (I don't find "bit length" very clear) a character count
and a collection of characters and using long long as the count then
small strings have a heft overhead.

"hello" has more space devoted to the count than the character data
```
 0
2/16/2010 9:07:37 AM
```"spinoza1111" <spinoza1111@yahoo.com> wrote in message
On Feb 16, 2:57 am, "Chris M. Thomasson" <n...@spam.invalid> wrote:
> > "spinoza1111" <spinoza1...@yahoo.com> wrote in message
> >
> > [...]
> >
> > > It was hard to get my doubly linked list working, but I did. It would
> > > have been nice to have a separate tool for linked lists. Richard
> > > Heathfield appears to have published such a tool in 2000, in C
> > > Unleashed, but as far as I can determine (see elsethread), the
> > > Dickiemaster copies the actual values into the list. This would have
> > > blown me to Kingdom Come. I THINK the Heathman wanted to avoid using
> > > pointer to void (he is welcome to comment here).
> >
> > I don't know why Richard implemented a simple linked-list that way. I
> > take
> > it he is not that fond of intrusive linked lists.

> But his solution IS intrusive, unless by "intrusive" you mean
> something else.

I mean why not embed the list node directly into a data-structure? The list
nodes intrudes into the object.

> > A linked list of pointers (the right way) is only "intrusive" in that
> > it consists of a set of eyes looking at data.
> >
> > trouble, since you're both looking at data and grabbing it. Eyes and
> > paws.

> > > However, preprocessor macro implementation of linked list would avoid
> > > both copying entries and pointer to void. But it would be at that
> > > point in which I would ask myself, like Ross Perot's running mate VAdm
> > > Jim Stockdale in 1992, "Who am I? Why am I here? And why am I not
> > > coding in C Sharp, or getting laid?"
> >
> > What about intrusive data-structures that do not require any copying
> > and/or
> > void pointers? I use them all the time.

> That was my idea...use a macro for strong typing.

I was thinking of the following technique. Here, let me quickly code up a
simple example:
_______________________________________________________________
#include <stdio.h>
#include <stddef.h>

#define CONTAINS(mp_self, mp_type, mp_member) \
((mp_type*)(((unsigned char*)(mp_self)) - \
offsetof(mp_type, mp_member)))

struct slist
{
struct slist* next;
};

#define SLIST_SINIT { NULL }

void
slpush(struct slist* const self,
struct slist* node)
{
node->next = self->next;
self->next = node;
}

struct slist*
slpop(struct slist* const self)
{
struct slist* node = self->next;
if (node) self->next = node->next;
return node;
}

void
slreverse(struct slist* const self)
{
struct slist* node = self->next;

while (node)
{
struct slist* next = node->next;
node = next;
}

}

struct foo
{
char const* string;
struct slist node1;
struct slist node2;
};

#define FOO_SINIT(mp_string) \
{ (mp_string), SLIST_SINIT, SLIST_SINIT }

int main()
{
struct slist* node;
struct slist list1 = SLIST_SINIT;
struct slist list2 = SLIST_SINIT;

struct foo foo[] =
{
FOO_SINIT("One"),
FOO_SINIT("Two"),
FOO_SINIT("Three"),
FOO_SINIT("Four"),
FOO_SINIT("Five")
};

size_t i;
size_t depth = sizeof(foo) / sizeof(foo[0]);

for (i = 0; i < depth; ++i)
{
slpush(&list1, &foo[i].node1);
slpush(&list2, &foo[i].node2);
}

slreverse(&list2);

while (node)
{
struct foo* f = CONTAINS(node, struct foo, node1);

printf("(%p)->foo(%s)\n",
(void*)f,
f->string);

node = node->next;
}

puts("--------------------------------------------------");

while (node)
{
struct foo* f = CONTAINS(node, struct foo, node2);

printf("(%p)->foo(%s)\n",
(void*)f,
f->string);

node = node->next;
}

return 0;
}
_______________________________________________________________

The `struct slist' objects intrude upon the `struct foo' objects. Now, you
can create a generic set of functions that operate on `struct slist' objects
regardless of what they are embedded within (e.g., see the `slreverse()'
function).

```
 0
no6 (2828)
2/16/2010 9:31:48 AM
```On Feb 16, 5:07=A0pm, Nick Keighley <nick_keighley_nos...@hotmail.com>
wrote:
> On 15 Feb, 14:40,spinoza1111<spinoza1...@yahoo.com> wrote:
>
> > On Feb 15, 6:32=A0pm, websnarf <websn...@gmail.com> wrote:
> > > On Feb 14, 8:16=A0pm, "Chris M. Thomasson" <n...@spam.invalid> wrote:
> > > > On Feb 15, 7:33 am, websnarf <websn...@gmail.com> wrote:
> > Until very recently, I thought that bit length was an unacceptable
> > restriction on string length, but if one ponders the scale of long
> > long, it is more than enough.
>
> if you mean (I don't find "bit length" very clear) a character count
> and a collection of characters and using long long as the count then
> small strings have a heft overhead.
>
> "hello" has more space devoted to the count than the character data

Hmm, good point. The vast majority of strings fit in int or even short
or even byte, and the counts of strings probably increase
exponentially from long long to long to int to short to byte.

OK, use a byte for string length in a linked list. When you need the
total length sum the byte lengths in a long long. Shouldn't be a
problem for 90% of all strings.

Then, "hello" would take

1 byte length
4 (?) byte pointer to value
6 bytes for the value

You do agree that you're gonna need more bytes than are in the string.
We could get rid of the NUL bytes by storing the segment length and
not the length of the string in the linked list node, and whenever we
need the "real" length, walking the list.

But note that I fall here into the trap that Heathfield apparently
fell into in C Unleashed with his less than amazing linked list: some
calls to my string thingie blow up.

Better, then, to put the total length in the first node.
```
 0
spinoza1111 (3246)
2/16/2010 9:34:46 AM
```On Feb 16, 5:31=A0pm, "Chris M. Thomasson" <n...@spam.invalid> wrote:
> "spinoza1111" <spinoza1...@yahoo.com> wrote in message
>
> On Feb 16, 2:57 am, "Chris M. Thomasson" <n...@spam.invalid> wrote:
>
>
>
>
>
> > > "spinoza1111" <spinoza1...@yahoo.com> wrote in message
>
...
> > > [...]
>
> > > > It was hard to get my doubly linked list working, but I did. It wou=
ld
> > > > have been nice to have a separate tool for linked lists. Richard
> > > > Heathfield appears to have published such a tool in 2000, in C
> > > > Unleashed, but as far as I can determine (see elsethread), the
> > > > Dickiemaster copies the actual values into the list. This would hav=
e
> > > > blown me to Kingdom Come. I THINK the Heathman wanted to avoid usin=
g
> > > > pointer to void (he is welcome to comment here).
>
> > > I don't know why Richard implemented a simple linked-list that way. I
> > > take
> > > it he is not that fond of intrusive linked lists.
> > But his solution IS intrusive, unless by "intrusive" you mean
> > something else.
>
> I mean why not embed the list node directly into a data-structure? The li=
st
> nodes intrudes into the object.
>
>
>
>
>
> > > A linked list of pointers (the right way) is only "intrusive" in that
> > > it consists of a set of eyes looking at data.
>
> > > trouble, since you're both looking at data and grabbing it. Eyes and
> > > paws.
> > > > However, preprocessor macro implementation of linked list would avo=
id
> > > > both copying entries and pointer to void. But it would be at that
> > > > point in which I would ask myself, like Ross Perot's running mate V=
> > > > Jim Stockdale in 1992, "Who am I? Why am I here? And why am I not
> > > > coding in C Sharp, or getting laid?"
>
> > > What about intrusive data-structures that do not require any copying
> > > and/or
> > > void pointers? I use them all the time.
> > That was my idea...use a macro for strong typing.
>
> I was thinking of the following technique. Here, let me quickly code up a
> simple example:
> _______________________________________________________________
> #include <stdio.h>
> #include <stddef.h>
>
> #define CONTAINS(mp_self, mp_type, mp_member) \
> =A0 ((mp_type*)(((unsigned char*)(mp_self)) - \
> =A0 =A0 offsetof(mp_type, mp_member)))
>
> struct slist
> {
> =A0 =A0 struct slist* next;
>
> };
>
> #define SLIST_SINIT { NULL }
>
>
> void
> slpush(struct slist* const self,
> =A0 =A0 =A0 =A0struct slist* node)
> {
> =A0 =A0 node->next =3D self->next;
> =A0 =A0 self->next =3D node;
>
> }
>
> struct slist*
> slpop(struct slist* const self)
> {
> =A0 =A0 struct slist* node =3D self->next;
> =A0 =A0 if (node) self->next =3D node->next;
> =A0 =A0 return node;
>
> }
>
> void
> slreverse(struct slist* const self)
> {
> =A0 =A0 struct slist* head =3D NULL;
> =A0 =A0 struct slist* node =3D self->next;
>
> =A0 =A0 while (node)
> =A0 =A0 {
> =A0 =A0 =A0 =A0 struct slist* next =3D node->next;
> =A0 =A0 =A0 =A0 node->next =3D head;
> =A0 =A0 =A0 =A0 head =3D node;
> =A0 =A0 =A0 =A0 node =3D next;
> =A0 =A0 }
>
> =A0 =A0 self->next =3D head;
>
> }
>
> struct foo
> {
> =A0 =A0 char const* string;
> =A0 =A0 struct slist node1;
> =A0 =A0 struct slist node2;
>
> };
>
> #define FOO_SINIT(mp_string) \
> =A0 =A0 { (mp_string), SLIST_SINIT, SLIST_SINIT }
>
> int main()
> {
> =A0 =A0 struct slist* node;
> =A0 =A0 struct slist list1 =3D SLIST_SINIT;
> =A0 =A0 struct slist list2 =3D SLIST_SINIT;
>
> =A0 =A0 struct foo foo[] =3D
> =A0 =A0 {
> =A0 =A0 =A0 =A0 FOO_SINIT("One"),
> =A0 =A0 =A0 =A0 FOO_SINIT("Two"),
> =A0 =A0 =A0 =A0 FOO_SINIT("Three"),
> =A0 =A0 =A0 =A0 FOO_SINIT("Four"),
> =A0 =A0 =A0 =A0 FOO_SINIT("Five")
> =A0 =A0 };
>
> =A0 =A0 size_t i;
> =A0 =A0 size_t depth =3D sizeof(foo) / sizeof(foo[0]);
>
> =A0 =A0 for (i =3D 0; i < depth; ++i)
> =A0 =A0 {
> =A0 =A0 =A0 =A0 slpush(&list1, &foo[i].node1);
> =A0 =A0 =A0 =A0 slpush(&list2, &foo[i].node2);
> =A0 =A0 }
>
> =A0 =A0 slreverse(&list2);
>
> =A0 =A0 node =3D slhead(&list1);
>
> =A0 =A0 while (node)
> =A0 =A0 {
> =A0 =A0 =A0 =A0 struct foo* f =3D CONTAINS(node, struct foo, node1);
>
> =A0 =A0 =A0 =A0 printf("(%p)->foo(%s)\n",
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(void*)f,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0f->string);
>
> =A0 =A0 =A0 =A0 node =3D node->next;
> =A0 =A0 }
>
> =A0 =A0 puts("--------------------------------------------------");
>
> =A0 =A0 node =3D slhead(&list2);
>
> =A0 =A0 while (node)
> =A0 =A0 {
> =A0 =A0 =A0 =A0 struct foo* f =3D CONTAINS(node, struct foo, node2);
>
> =A0 =A0 =A0 =A0 printf("(%p)->foo(%s)\n",
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(void*)f,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0f->string);
>
> =A0 =A0 =A0 =A0 node =3D node->next;
> =A0 =A0 }
>
> =A0 =A0 return 0;}
>
> _______________________________________________________________
>
> The `struct slist' objects intrude upon the `struct foo' objects. Now, yo=
u
> can create a generic set of functions that operate on `struct slist' obje=
cts
> regardless of what they are embedded within (e.g., see the `slreverse()'
> function).

Very clever. I like this idea. Lists remain pure lists. Very elegant.
But: I do not understand how, if I have ONLY a foo, to find the next
foo.
```
 0
spinoza1111 (3246)
2/16/2010 12:33:36 PM
```On Feb 16, 2:28=A0am, spinoza1111 <spinoza1...@yahoo.com> wrote:
> On Feb 16, 12:30=A0am, Julienne Walker <happyfro...@hotmail.com> wrote:
>
> > On Feb 15, 9:40=A0am,spinoza1111<spinoza1...@yahoo.com> wrote:
>
> > > However, for easy modification, I don't think a doubly linked list
> > > representation of strings with a length code could be beat.
>
> > Indeed. Too bad linked data structures have a tendency toward poor
> > cache performance. And depending on how the list is implemented, many
> > programmers (even in C#) would likely balk at the extra overhead of
> > storing and following links for a "mere" string.
>
> psychological.

They *would* have to follow the links unless there are fingers into
the list. One of the basic limitations of a linked list is a lack of
random access. Assuming you're performing a search and modify on a
string, that limitation isn't a big deal, but you'll still need to
traverse the list in one form or another.

The overhead may be psychological in this day and age, but I think
you'll agree that one node per character is wasteful in terms of
space. Even if you use Unicode and a suitable type to represent
Unicode characters, we're still looking at approximately twice the
space for a link (either an integer index or a pointer) to an

One can alleviate that waste by storing arrays of characters in each
node rather than a single character, but that increases the complexity
of the data structure, which means you're probably going to see a
performance hit. Whether that hit is significant would require
profiling, but even if it weren't, I'd say the benefit of a linked
list is no longer clear.

There are many ways of implementing a linked list, with suggests that
you're thinking of a different implementation than I. Perhaps you
could describe the implementation you're thinking of, where following

> Frankly, Julienne, I'm tired of the facility in which
> ordinary garden-variety transform "the need to think" into "wasting
> overhead" as if their brains =3D=3D their computer.

I can't decide if you're insulting me or using my post to enable
attacks on your usual clc nemeses. Either way I think I'll simply
ignore it and focus on the topic at hand.

> > > copies the actual values into the list. This would have
> > > blown me to Kingdom Come.
>
> > Can you elaborate on this? I'm not sure I fully understand what you
> > mean.
>
> It appeared to me that Richard's "general purpose linked list" of 2000
> copies the values of anything passed to it into nodes of the linked
> list. But if I were (in a blue moon) to use his code to re-present
> strings as linked list, then he'd copy unbounded amounts of data
> inside his code.

Thank you. That's what I was thinking, but felt the need to ask for
clarification. Unfortunately I'm unable to comment further at this
time because C Unleashed isn't on my bookshelf at work.
```
 0
2/16/2010 1:59:22 PM
```On 16/02/2010 07:32, spinoza1111 wrote:
> On Feb 16, 12:21 am, Tim Streater<timstrea...@waitrose.com>  wrote:

>> Which myth is that then? I'm dealing with reality - that of being left
>> with an undocumented mess to look after, because the clown in question
>> preferred to do something "cool" and "neat", rather than what he was
>> paid to do.
>
> What was he paid to do? Something hot and sloppy?

I observe that, like all fascists, you see the world in terms of black
and white. No - he was paid to do an adequate and workmanlike job,
taking data output from one program and changing it to be suitable to be
input by another. A few pages of code at most, and not worth
generalising since the whole suite was likely to be ditched within a
year or so.

We don't need "War and Peace" when the sixpenny paperback does the job
just as well.

>> By the way, I don't object to his doing something "cool" and "neat", but
>> on his own time, OK?
>
> But on the job we must produce crap at speed?

See above.

>> Well, gee, life's a bitch sometimes, ain't it though! I'll let the good
>> people of Haiti know that while they might think *they* have problems,
>> poor Spinny has to deal with feof().
>
> Haiti? OK, an old argument: don't complain about anything, you have no
> right given "the weight of the world". The problem being that Haiti's
> problems were CAUSED by US corporations in the same system in which
> they don't give programmers, *as a matter of principle* enough time to
> do a quality job.

Gosh, US Corps can trigger earthquakes, eh? Marvellous, what will they
think of next?

--
Tim

"That the freedom of speech and debates or proceedings in Parliament
ought not to be impeached or questioned in any court or place out of
Parliament"

Bill of Rights 1689
```
 0
timstreater (945)
2/16/2010 11:00:56 PM
```"Julienne Walker" <happyfrosty@hotmail.com> wrote in message

[...]

IMVHO, a linked-list amortized string implementation can get along fairly
well with a "large" amount of text. For instance, I would personally not
want to store the text that makes up a fairly verbose well-read novel in a
single NUL terminated string. Humm... You should probably break the massive
data apart into an amortized linked data-structure. Amortized in the sense
that multiple characters/whatever can exist on a per-node basis.

```
 0
no6 (2828)
2/16/2010 11:09:51 PM
```On 2010-02-16, Chris M. Thomasson <no@spam.invalid> wrote:
> IMVHO, a linked-list amortized string implementation can get along fairly
> well with a "large" amount of text. For instance, I would personally not
> want to store the text that makes up a fairly verbose well-read novel in a
> single NUL terminated string. Humm... You should probably break the massive
> data apart into an amortized linked data-structure. Amortized in the sense
> that multiple characters/whatever can exist on a per-node basis.

Anyone planning to invent this would be well-served by studying the "mbufs"
in the BSD networking stack.

Not necessarily imitating, or using.  But studying.  They are a fairly
carefully-considered approach to the question of storing widely variable
amounts of data in a listish form, with some variance in the amount of data
in each node.

-s
--
Copyright 2010, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
```
 0
usenet-nospam (2309)
2/16/2010 11:32:11 PM
```On Feb 17, 7:00=A0am, Tim Streater <timstrea...@waitrose.com> wrote:
> On 16/02/2010 07:32,spinoza1111wrote:
>
> > On Feb 16, 12:21 am, Tim Streater<timstrea...@waitrose.com> =A0wrote:
> >> Which myth is that then? I'm dealing with reality - that of being left
> >> with an undocumented mess to look after, because the clown in question
> >> preferred to do something "cool" and "neat", rather than what he was
> >> paid to do.
>
> > What was he paid to do? Something hot and sloppy?
>
> I observe that, like all fascists, you see the world in terms of black
> and white. No - he was paid to do an adequate and workmanlike job,
> taking data output from one program and changing it to be suitable to be
> input by another. A few pages of code at most, and not worth
> generalising since the whole suite was likely to be ditched within a
> year or so.
>
> We don't need "War and Peace" when the sixpenny paperback does the job
> just as well.

The problem is that it's always like that.  Management never wants to
invest enough.

The guy may have been a fool. But I regard these stories as primarily
myths, since in all probability you weren't any more qualified than he
to tell what was needed.

>
> >> By the way, I don't object to his doing something "cool" and "neat", b=
ut
> >> on his own time, OK?
>
> > But on the job we must produce crap at speed?
>
> See above.
>
> >> Well, gee, life's a bitch sometimes, ain't it though! I'll let the goo=
d
> >> people of Haiti know that while they might think *they* have problems,
> >> poor Spinny has to deal with feof().
>
> > Haiti? OK, an old argument: don't complain about anything, you have no
> > right given "the weight of the world". The problem being that Haiti's
> > problems were CAUSED by US corporations in the same system in which
> > they don't give programmers, *as a matter of principle* enough time to
> > do a quality job.
>
> Gosh, US Corps can trigger earthquakes, eh? Marvellous, what will they
> think of next?

Read history. Haiti was in permanent debt as a result of being forced
by the US, Britain and France to pay "reparations for slavery" AS THE
SLAVE SOCIETY in 1825: French pigs wanted to be compensated when in
1804, Haitiennes fought for and won their freedom...in a war which
forced Napoleon to sell what's now more than half the United States to
the USA in the Louisiana Purchase, which was greatly, that is, to the
United States' advantage. When in 1910 these debts overwhelmed Haiti,
the City Bank of New York (today Citicorp) forced Haiti to sell its
central bank at fire-sale prices.

The United States Marines were sent in 1915 by President Wilson to
handle the chaos that resulted from the poverty that resulted from
Citicorp's theft, and a US-friendly dictator (Duvalier) and his son
terrorized Haiti until the 1980s.

A popular leader (Aristide) who threatened to act in the interest of
Haiti's poor was overthrown by a Bush-sponsored coup in 2004 while the
USA was distracted by Iraq, and kidnapped by US Marines "for his own
protection" and taken to Africa.

The country collapsed in January as a result of two hundred years of
debt slavery and persecution by the "civilized" world for having the
balls to take the US Declaration of Independence and the French
"Declaration de Droites de l'Homme et Citoyen" seriously. A 7.0
earthquake in San Francisco in 1989 at the start of the World Series
killed only a few dozen people and destroyed no major structures,
because Californians HAD THE MONEY to build earthquake safe: that
magnitude in Haiti has killed uncounted numbers of people because of
the two hundred year bullying of Haiti for being a country of  men who
freed themselves. Just as people who post here with grownup dignity
are targeted, in fact, the Haitiennes have been targeted. I hope they
swim to Florida and take over.
>
> --
> Tim
>
> "That the freedom of speech and debates or proceedings in Parliament
> ought not to be impeached or questioned in any court or place out of
> Parliament"
>
> Bill of Rights 1689

```
 0
spinoza1111 (3246)
2/17/2010 12:08:30 AM
```On Feb 16, 9:59=A0pm, Julienne Walker <happyfro...@hotmail.com> wrote:
> On Feb 16, 2:28=A0am,spinoza1111<spinoza1...@yahoo.com> wrote:
>
> > On Feb 16, 12:30=A0am, Julienne Walker <happyfro...@hotmail.com> wrote:
>
> > > On Feb 15, 9:40=A0am,spinoza1111<spinoza1...@yahoo.com> wrote:
>
> > > > However, for easy modification, I don't think a doubly linked list
> > > > representation of strings with a length code could be beat.
>
> > > Indeed. Too bad linked data structures have a tendency toward poor
> > > cache performance. And depending on how the list is implemented, many
> > > programmers (even in C#) would likely balk at the extra overhead of
> > > storing and following links for a "mere" string.
>
> > psychological.
>
> They *would* have to follow the links unless there are fingers into
> the list. One of the basic limitations of a linked list is a lack of
> random access. Assuming you're performing a search and modify on a
> string, that limitation isn't a big deal, but you'll still need to
> traverse the list in one form or another.

That is correct, but the string manager can cache an index randomly in
the string.
>
> The overhead may be psychological in this day and age, but I think
> you'll agree that one node per character is wasteful in terms of
> space. Even if you use Unicode and a suitable type to represent
> Unicode characters, we're still looking at approximately twice the
> space for a link (either an integer index or a pointer) to an

Oops, perhaps I need to clarify. You would store the addresses of
blocks of characters in each node, that is, pointers to segments in
mallocated storage with a length code expressing the segment length
rather than a Nul in the segment. Putting characters in nodes would
make what I think was Richard Heathfield's mistake: a linked list as a
collection of actual squashed butterflies (a Lady Godey's Fairy Book)
and not photographs of (links to) data.
>
> One can alleviate that waste by storing arrays of characters in each
> node rather than a single character, but that increases the complexity

No no no no no. LINKS, please. A pointer to the segment in mallocated
space and its length.

> of the data structure, which means you're probably going to see a
> performance hit. Whether that hit is significant would require
> profiling, but even if it weren't, I'd say the benefit of a linked
> list is no longer clear.

My entire point was that Richard's approach is wrong. In fact, a
programmer with uni compsci would never have done what he did.
>
> There are many ways of implementing a linked list, with suggests that
> you're thinking of a different implementation than I. Perhaps you
> could describe the implementation you're thinking of, where following

{
char * ptrToSegment; // Photograph of the Fairy, not the Fairy's
corpse
int segmentLength;   // Who needs Nul? We don't need no steenking
Nul
};

>
> > Frankly, Julienne, I'm tired of the facility in which
> > ordinary garden-variety transform "the need to think" into "wasting
> > overhead" as if their brains =3D=3D their computer.
>
> I can't decide if you're insulting me or using my post to enable
> attacks on your usual clc nemeses. Either way I think I'll simply
> ignore it and focus on the topic at hand.

Neither. What concerns me is that in nearly all offices, a language
game is played that produces crumby software. Here, it's resistance to
good solutions which are hard for some to think about based on false
appeals to a misapprehension of "structured programming" and the false
must be an inefficient kludge".

And I reserve the right to answer the excessive bullying that occurs
in this newsgroup.

>
> > > > copies the actual values into the list. This would have
> > > > blown me to Kingdom Come.
>
> > > Can you elaborate on this? I'm not sure I fully understand what you
> > > mean.
>
> > It appeared to me that Richard's "general purpose linked list" of 2000
> > copies the values of anything passed to it into nodes of the linked
> > list. But if I were (in a blue moon) to use his code to re-present
> > strings as linked list, then he'd copy unbounded amounts of data
> > inside his code.
>
> Thank you. That's what I was thinking, but felt the need to ask for
> clarification. Unfortunately I'm unable to comment further at this
> time because C Unleashed isn't on my bookshelf at work.

```
 0
spinoza1111 (3246)
2/17/2010 12:22:47 AM
```"Seebs" <usenet-nospam@seebs.net> wrote in message
news:slrnhnmavs.3pi.usenet-nospam@guild.seebs.net...
> On 2010-02-16, Chris M. Thomasson <no@spam.invalid> wrote:
>> IMVHO, a linked-list amortized string implementation can get along fairly
>> well with a "large" amount of text. For instance, I would personally not
>> want to store the text that makes up a fairly verbose well-read novel in
>> a
>> single NUL terminated string. Humm... You should probably break the
>> massive
>> data apart into an amortized linked data-structure. Amortized in the
>> sense
>> that multiple characters/whatever can exist on a per-node basis.
>
> Anyone planning to invent this would be well-served by studying the
> "mbufs"
> in the BSD networking stack.

Indeed. I also enjoy the well known intrusive list technique:
_______________________________________________________
struct node
{
struct node* next;
};

struct foo
{
struct node node;
/* [whatever] */
};

#define foo_from_node(n) ((struct foo*)(n))
_______________________________________________________

The Linux User/Kernel and Windows User/Kernel-space code is quite fond of
intrusive data-structures as well.

> Not necessarily imitating, or using.  But studying.  They are a fairly
> carefully-considered approach to the question of storing widely variable
> amounts of data in a listish form, with some variance in the amount of
> data
> in each node.

Agreed.

```
 0
no6 (2828)
2/17/2010 12:22:59 AM
```On Feb 17, 2:08=A0am, spinoza1111 <spinoza1...@yahoo.com> wrote:
> A 7.0
> earthquake in San Francisco in 1989 at the start of the World Series
> killed only a few dozen people and destroyed no major structures,
> because Californians HAD THE MONEY to build earthquake safe:
>
You are absolutely right. Few if any Haitians died by act of God, but
because humans chose to build unstable structures, knowing that
earthquakes occasionally happen.

To put this back on topic, what's a professional Haitian architect to
do? Insisting on California-style structural standards would mean that
very few Haitians could afford to live in brick buildings.
```
 0
2/17/2010 6:25:31 AM
```On Feb 17, 2:25=A0pm, Malcolm McLean <malcolm.mcle...@btinternet.com>
wrote:
> On Feb 17, 2:08=A0am,spinoza1111<spinoza1...@yahoo.com> wrote:> A 7.0
> > earthquake in San Francisco in 1989 at the start of the World Series
> > killed only a few dozen people and destroyed no major structures,
> > because Californians HAD THE MONEY to build earthquake safe:
>
> You are absolutely right. Few if any Haitians died by act of God, but
> because humans chose to build unstable structures, knowing that
> earthquakes occasionally happen.
>
> To put this back on topic, what's a professional Haitian architect to
> do? Insisting on California-style structural standards would mean that
> very few Haitians could afford to live in brick buildings.

What is needed is to analyze Citicorp's current holdings in order to
trace what part are due to the fire sale price the City Bank of New
York (its former name) paid for Haiti's central bank in 1910, and then
force Citicorp, and all other banks unjustly enriched by the
reparations forced by France in 1825, to pay reparations for these
reparations, with a surcharge paid by French banks, and landowner
descendants for importing black Africans to Haiti in conditions of
slavery in the first place.

This would allow Haiti to rebuild itself adequately.

To stay on topic, this is something that could be done in part with
programming. But probably not in C, so it's not I admit on-topic. I
was replying to something I thought ignorant.
```
 0
spinoza1111 (3246)
2/17/2010 6:41:49 AM
```On 17 Feb, 00:22, spinoza1111 <spinoza1...@yahoo.com> wrote:
> On Feb 16, 9:59=A0pm, Julienne Walker <happyfro...@hotmail.com> wrote:
> > On Feb 16, 2:28=A0am,spinoza1111<spinoza1...@yahoo.com> wrote:
> > > On Feb 16, 12:30=A0am, Julienne Walker <happyfro...@hotmail.com> wrot=
e:
> > > > On Feb 15, 9:40=A0am,spinoza1111<spinoza1...@yahoo.com> wrote:

> > > > > However, for easy modification, I don't think a doubly linked lis=
t
> > > > > representation of strings with a length code could be beat.
>
> > > > Indeed. Too bad linked data structures have a tendency toward poor
> > > > cache performance. And depending on how the list is implemented, ma=
ny
> > > > programmers (even in C#) would likely balk at the extra overhead of
> > > > storing and following links for a "mere" string.
>
> > > psychological.

um, that's what links are for...

> > They *would* have to follow the links unless there are fingers into
> > the list. One of the basic limitations of a linked list is a lack of
> > random access. Assuming you're performing a search and modify on a
> > string, that limitation isn't a big deal, but you'll still need to
> > traverse the list in one form or another.
>
> That is correct, but the string manager can cache an index randomly in
> the string.

I've no idea what that means

> > The overhead may be psychological in this day and age, but I think
> > you'll agree that one node per character is wasteful in terms of
> > space. Even if you use Unicode and a suitable type to represent
> > Unicode characters, we're still looking at approximately twice the
> > space for a link (either an integer index or a pointer) to an
>
> Oops, perhaps I need to clarify. You would store the addresses of
> blocks of characters in each node, that is, pointers to segments in
> mallocated storage with a length code expressing the segment length
> rather than a Nul in the segment. Putting characters in nodes would
> make what I think was Richard Heathfield's mistake: a linked list as a
> collection of actual squashed butterflies (a Lady Godey's Fairy Book)
> and not photographs of (links to) data.

bizzare analogy.

So you're proposing a linked list of nodes each node containing a char
count and a pointer to a block of memory containing the actual chars.
Probably ok for some applications. Text editor? Bit heavy for small
strings.

> > One can alleviate that waste by storing arrays of characters in each
> > node rather than a single character, but that increases the complexity
>
> No no no no no. LINKS, please. A pointer to the segment in mallocated
> space and its length.

why so insistent? Whats wrong with variable sized nodes?

struct Node
{
struct Node *next;
int count;
char data [1];
};

then use "the struct hack" to allocate the memory

struct Node* make_node (char *c_str)
{
int size =3D strlen (c_str);
Node *new_node =3D malloc (sizeof(struct Node) + size - 1);
new_node->next =3D NULL;
new_node->count =3D size;
memcpy (new_node->data, c_str, size);
return new_node;
}

error checking ommitted. Untested code.

[note: there is a modified version of this function later on]

> > of the data structure, which means you're probably going to see a
> > performance hit. Whether that hit is significant would require
> > profiling, but even if it weren't, I'd say the benefit of a linked
> > list is no longer clear.
>
> My entire point was that Richard's approach is wrong. In fact, a
> programmer with uni compsci would never have done what he did.

I'll have to read C Unleashed but I doubt you're right.

> > There are many ways of implementing a linked list, with suggests that
> > you're thinking of a different implementation than I. Perhaps you
> > could describe the implementation you're thinking of, where following
>
> {
> =A0 =A0 char * ptrToSegment; // Photograph of the Fairy, not the Fairy's
> corpse
> =A0 =A0 int segmentLength; =A0 // Who needs Nul? We don't need no steenki=
ng
> Nul
> =A0 =A0 struct linkedListNode * next; // Aargh a linked list ye be
>
> };

and why wouldn't that link be followed. I've got a linked list and I

<snip>

> > > > > copies the actual values into the list. This would have
> > > > > blown me to Kingdom Come.
>
> > > > Can you elaborate on this? I'm not sure I fully understand what you
> > > > mean.
>
> > > It appeared to me that Richard's "general purpose linked list" of 200=
0
> > > copies the values of anything passed to it into nodes of the linked
> > > list. But if I were (in a blue moon) to use his code to re-present
> > > strings as linked list, then he'd copy unbounded amounts of data
> > > inside his code.

I'm still not clear how your version avoids the copying. Ah my above
code would look more like

struct Node* make_node (char *c_str)
{
int size =3D strlen (c_str);
Node *new_node =3D malloc (sizeof(struct Node) + size - 1);
new_node->next =3D NULL;
new_node->count =3D size;
new_node->data =3D c_str;
return new_node;
}

I suppose it depends where your strings come from. Again this would be
ok-ish for a text editor. The data comes from a file (the original
text) or user input (the edits)

> > Thank you. That's what I was thinking, but felt the need to ask for
> > clarification. Unfortunately I'm unable to comment further at this
> > time because C Unleashed isn't on my bookshelf at work.
```
 0
2/17/2010 9:15:41 AM
```On Feb 17, 11:15=A0am, Nick Keighley <nick_keighley_nos...@hotmail.com>
wrote:
> On 17 Feb, 00:22, spinoza1111 <spinoza1...@yahoo.com> wrote:
>
>
> > That is correct, but the string manager can cache an index randomly in
> > the string.
>
> I've no idea what that means
>
With a canonical linked list, one must always start traversing the
list at the head, and continue following links until one has got the
data one wants.

However it's possible to store additional pointers to points along the
list. So, for instance, if we have a linked list of 1000 entries, we
could have extra pointers at 100, 200, 300 and so on. To get to link
202, one simply checks the extra pointers (two comparisons), jumps
into the list at node 200, and carries along to 202 (3 comparisons),
thous retrieving the information in 5 comparisons instead of 203.

```
 0
2/17/2010 10:21:10 AM
```Malcolm McLean wrote:
> On Feb 17, 11:15 am, Nick Keighley <nick_keighley_nos...@hotmail.com>
> wrote:
>> On 17 Feb, 00:22, spinoza1111 <spinoza1...@yahoo.com> wrote:
>>
>>
>>> That is correct, but the string manager can cache an index randomly in
>>> the string.
>> I've no idea what that means
>>
> With a canonical linked list, one must always start traversing the
> list at the head, and continue following links until one has got the
> data one wants.
>
> However it's possible to store additional pointers to points along the
> list. So, for instance, if we have a linked list of 1000 entries, we
> could have extra pointers at 100, 200, 300 and so on. To get to link
> 202, one simply checks the extra pointers (two comparisons), jumps
> into the list at node 200, and carries along to 202 (3 comparisons),
> thous retrieving the information in 5 comparisons instead of 203.
>
Are we reinventing the weal?

http://www.sgi.com/tech/stl/Rope.html

Greets
```
 0
bmaxa209 (243)
2/17/2010 10:32:32 AM
```On 17/02/2010 00:08, spinoza1111 wrote:
> On Feb 17, 7:00 am, Tim Streater<timstrea...@waitrose.com>  wrote:
>> On 16/02/2010 07:32,spinoza1111wrote:
>>
>>> On Feb 16, 12:21 am, Tim Streater<timstrea...@waitrose.com>    wrote:
>>>> Which myth is that then? I'm dealing with reality - that of being left
>>>> with an undocumented mess to look after, because the clown in question
>>>> preferred to do something "cool" and "neat", rather than what he was
>>>> paid to do.
>>
>>> What was he paid to do? Something hot and sloppy?
>>
>> I observe that, like all fascists, you see the world in terms of black
>> and white. No - he was paid to do an adequate and workmanlike job,
>> taking data output from one program and changing it to be suitable to be
>> input by another. A few pages of code at most, and not worth
>> generalising since the whole suite was likely to be ditched within a
>> year or so.
>>
>> We don't need "War and Peace" when the sixpenny paperback does the job
>> just as well.
>
> The problem is that it's always like that.  Management never wants to
> invest enough.

What management may or may not want to do in general is neither here nor
there, like most of your observations. In this particular instance,
management wanted to invest just the right amount, but got something

> The guy may have been a fool. But I regard these stories as primarily
> myths, since in all probability you weren't any more qualified than he
> to tell what was needed.

Oh, "in all probability", eh? You have evidence to support this, do you?
(other then your usual b/s, I mean).

The guy was not a fool and his product worked. But the fact that it
needed him to make any modifications and turned into a black box once he
left, is proof enough that I was perfectly qualified to tell better that
he what was needed.

>>>> By the way, I don't object to his doing something "cool" and "neat", but
>>>> on his own time, OK?
>>
>>> But on the job we must produce crap at speed?
>>
>> See above.
>>
>>>> Well, gee, life's a bitch sometimes, ain't it though! I'll let the good
>>>> people of Haiti know that while they might think *they* have problems,
>>>> poor Spinny has to deal with feof().
>>
>>> Haiti? OK, an old argument: don't complain about anything, you have no
>>> right given "the weight of the world". The problem being that Haiti's
>>> problems were CAUSED by US corporations in the same system in which
>>> they don't give programmers, *as a matter of principle* enough time to
>>> do a quality job.
>>
>> Gosh, US Corps can trigger earthquakes, eh? Marvellous, what will they
>> think of next?
>
> Read history. Haiti was in permanent debt as a result of being forced
> by the US, Britain and France to pay "reparations for slavery" AS THE
> SLAVE SOCIETY in 1825:

earthquake like they had would be buggered, US Corps or not.

--
Tim

"That the freedom of speech and debates or proceedings in Parliament
ought not to be impeached or questioned in any court or place out of
Parliament"

Bill of Rights 1689
```
 0
timstreater (945)
2/17/2010 11:22:47 AM
```On Feb 17, 7:22=A0pm, Tim Streater <timstrea...@waitrose.com> wrote:
> On 17/02/2010 00:08,spinoza1111wrote:
>
>
>
>
>
> > On Feb 17, 7:00 am, Tim Streater<timstrea...@waitrose.com> =A0wrote:
> >> On 16/02/2010 07:32,spinoza1111wrote:
>
> >>> On Feb 16, 12:21 am, Tim Streater<timstrea...@waitrose.com> =A0 =A0wr=
ote:
> >>>> Which myth is that then? I'm dealing with reality - that of being le=
ft
> >>>> with an undocumented mess to look after, because the clown in questi=
on
> >>>> preferred to do something "cool" and "neat", rather than what he was
> >>>> paid to do.
>
> >>> What was he paid to do? Something hot and sloppy?
>
> >> I observe that, like all fascists, you see the world in terms of black
> >> and white. No - he was paid to do an adequate and workmanlike job,
> >> taking data output from one program and changing it to be suitable to =
be
> >> input by another. A few pages of code at most, and not worth
> >> generalising since the whole suite was likely to be ditched within a
> >> year or so.
>
> >> We don't need "War and Peace" when the sixpenny paperback does the job
> >> just as well.
>
> > The problem is that it's always like that. =A0Management never wants to
> > invest enough.
>
> What management may or may not want to do in general is neither here nor
> there, like most of your observations. In this particular instance,
> management wanted to invest just the right amount, but got something

But it worked, you say below. My suspicion is that it became "useless"
because you and your mates were unwilling and unable to maintain it,
and this may be because it was crap (in which case the original
programmer is to blame), over your heads (in which case the original
programmer is partly to blame) or an excellent piece of code (in which
case, you're to blame).
>
> > The guy may have been a fool. But I regard these stories as primarily
> > myths, since in all probability you weren't any more qualified than he
> > to tell what was needed.
>
> Oh, "in all probability", eh? You have evidence to support this, do you?
> (other then your usual b/s, I mean).
>
> The guy was not a fool and his product worked. But the fact that it
> needed him to make any modifications and turned into a black box once he
> left, is proof enough that I was perfectly qualified to tell better that
> he what was needed.

That may be the case. But given what appears to me to be a VERY low
level of skill on the part of the somewhat random selection of
programmers who post here, the program the guy wrote may have been
"too difficult to maintain" not as an inherent property, but because
you were unable/unwilling to maintain it.

His intention seems to have been to make it more easy to maintain by
writing a sort of "conversion compiler". Sometimes such tools are more
trouble than they are worth, because to use them you have to learn
what some clown's ideas of what a "language for file conversion" is.

Other times, however, corporate programmers merely have a learning
disorder or mental block when it comes to being able to connect with
program texts in a different style, and simply refuse to learn a
program written in a different style or with a different approach from
their favorite styles and approaches, for the same reason I've stated

For the same reason they resented having to read Shakespeare in high
school to pass a class, they resent some pretentious ponce writing
code in an unfamiliar way. The pretentious ponce may be another
Shakespeare, or in actuality a pretentious ponce, but more usually
from a statistical perspective alone he's probably somewhere in
between.

Did you in fact envy his creativity and skill? And does not the
corporate way discourage dependence on creativity and skill?

If there was only one good way to convert the file, then the guy was
either a pretentious ponce or overqualified. If however he saw
something you did not, then he was a "genius". The truth is probably
somewhere in between.

>
>
>
>
>
> >>>> By the way, I don't object to his doing something "cool" and "neat",=
but
> >>>> on his own time, OK?
>
> >>> But on the job we must produce crap at speed?
>
> >> See above.
>
> >>>> Well, gee, life's a bitch sometimes, ain't it though! I'll let the g=
ood
> >>>> people of Haiti know that while they might think *they* have problem=
s,
> >>>> poor Spinny has to deal with feof().
>
> >>> Haiti? OK, an old argument: don't complain about anything, you have n=
o
> >>> right given "the weight of the world". The problem being that Haiti's
> >>> problems were CAUSED by US corporations in the same system in which
> >>> they don't give programmers, *as a matter of principle* enough time t=
o
> >>> do a quality job.
>
> >> Gosh, US Corps can trigger earthquakes, eh? Marvellous, what will they
> >> think of next?
>
> > Read history. Haiti was in permanent debt as a result of being forced
> > by the US, Britain and France to pay "reparations for slavery" AS THE
> > SLAVE SOCIETY in 1825:
>
> earthquake like they had would be buggered, US Corps or not.

No again. Again, the San Francisco Bay area had a Richter 7.0 scale
earthquake at the start of the World Series in 1989, and casualties
and damage were minimal.
>
> --
> Tim
>
> "That the freedom of speech and debates or proceedings in Parliament
> ought not to be impeached or questioned in any court or place out of
> Parliament"
>
> Bill of Rights 1689

```
 0
spinoza1111 (3246)
2/17/2010 1:42:48 PM
```On Feb 17, 6:32=A0pm, Branimir Maksimovic <bm...@hotmail.com> wrote:
> Malcolm McLean wrote:
> > On Feb 17, 11:15 am, Nick Keighley <nick_keighley_nos...@hotmail.com>
> > wrote:
> >> On 17 Feb, 00:22,spinoza1111<spinoza1...@yahoo.com> wrote:
>
> >>> That is correct, but the string manager can cache an index randomly i=
n
> >>> the string.
> >> I've no idea what that means
>
> > With a canonical linked list, one must always start traversing the
> > list at the head, and continue following links until one has got the
> > data one wants.
>
> > However it's possible to store additional pointers to points along the
> > list. So, for instance, if we have a linked list of 1000 entries, we
> > could have extra pointers at 100, 200, 300 and so on. To get to link
> > 202, one simply checks the extra pointers (two comparisons), jumps
> > into the list at node 200, and carries along to 202 (3 comparisons),
> > thous retrieving the information in 5 comparisons instead of 203.
>
> Are we reinventing the weal?

Yes.
>
> http://www.sgi.com/tech/stl/Rope.html
>
> Greets

```
 0
spinoza1111 (3246)
2/17/2010 1:43:20 PM
```On Feb 17, 6:21=A0pm, Malcolm McLean <malcolm.mcle...@btinternet.com>
wrote:
> On Feb 17, 11:15=A0am, Nick Keighley <nick_keighley_nos...@hotmail.com>
> wrote:> On 17 Feb, 00:22,spinoza1111<spinoza1...@yahoo.com> wrote:
>
> > > That is correct, but the string manager can cache an index randomly i=
n
> > > the string.
>
> > I've no idea what that means
>
> With a canonical linked list, one must always start traversing the
> list at the head, and continue following links until one has got the
> data one wants.
>
> However it's possible to store additional pointers to points along the
> list. So, for instance, if we have a linked list of 1000 entries, we
> could have extra pointers at 100, 200, 300 and so on. To get to link
> 202, one simply checks the extra pointers (two comparisons), jumps
> into the list at node 200, and carries along to 202 (3 comparisons),
> thous retrieving the information in 5 comparisons instead of 203.

That's what I was thinking, Malcolm.
```
 0
spinoza1111 (3246)
2/17/2010 1:43:51 PM
```On Feb 16, 7:22=A0pm, spinoza1111 <spinoza1...@yahoo.com> wrote:
> On Feb 16, 9:59=A0pm, Julienne Walker <happyfro...@hotmail.com> wrote:
> > On Feb 16, 2:28=A0am,spinoza1111<spinoza1...@yahoo.com> wrote:
>
> > One can alleviate that waste by storing arrays of characters in each
> > node rather than a single character, but that increases the complexity
>
> No no no no no. LINKS, please. A pointer to the segment in mallocated
> space and its length.

A detail quite irrelevant to my point. Now you're managing a linked
list, blocks of contiguous characters, *and* the relationship between
them to represent a single string. If the original goal is easy
modification, I'd be dubious about how successful this design is
compared to the simpler list of characters or block of characters.

> > of the data structure, which means you're probably going to see a
> > performance hit. Whether that hit is significant would require
> > profiling, but even if it weren't, I'd say the benefit of a linked
> > list is no longer clear.
>
> My entire point was that Richard's approach is wrong. In fact, a
> programmer with uni compsci would never have done what he did.

I went home and checked my copy of the book. Personally, I think
you're overreacting. The C Unleashed design is a viable one in that
the data structure owns its data, as opposed to having the data owned
by something else and merely storing pointers to said data. In the
former case the data structure can make specific claims of correctness
and integrity while in the latter case you can end up with dangling
pointers and unexpected aliasing. On the down side, in the former case
you end up copying data around when it might not be necessary, and
making copies might not be desirable from a functionality standpoint.

software design. Choose the one that best suits your needs, and you'll
end up with higher quality software. Being dogmatic about one or the

> > > Frankly, Julienne, I'm tired of the facility in which
> > > ordinary garden-variety transform "the need to think" into "wasting
> > > overhead" as if their brains =3D=3D their computer.
>
> > I can't decide if you're insulting me or using my post to enable
> > attacks on your usual clc nemeses. Either way I think I'll simply
> > ignore it and focus on the topic at hand.
>
> Neither. What concerns me is that in nearly all offices, a language
> game is played that produces crumby software. Here, it's resistance to
> good solutions which are hard for some to think about based on false
> appeals to a misapprehension of "structured programming" and the false
> must be an inefficient kludge".

May I direct you to the irony of this statement and your resistance to
the solution from C Unleashed (which is no worse than your stated
alternative, just different)? While I prefer not to presume to say
*why* someone is resistant to alternatives, it often strikes me as a
matter of ego rather than logic. In a manner of speaking: "I'd do it
this way, so this way is right. Your way isn't how I'd do it, so your
way is wrong".

> And I reserve the right to answer the excessive bullying that occurs
> in this newsgroup.

I'd recommend that you take care not to cause too much collateral
damage then. But I'm not sure that recommendation is worth the
bandwidth from me to you because, if I recall correctly, one of your
stated goals was to damage this newsgroup as much as possible.
```
 0
2/17/2010 2:07:06 PM
```On Feb 17, 10:07=A0pm, Julienne Walker <happyfro...@hotmail.com> wrote:
> On Feb 16, 7:22=A0pm,spinoza1111<spinoza1...@yahoo.com> wrote:
>
> > On Feb 16, 9:59=A0pm, Julienne Walker <happyfro...@hotmail.com> wrote:
> > > On Feb 16, 2:28=A0am,spinoza1111<spinoza1...@yahoo.com> wrote:
>
> > > One can alleviate that waste by storing arrays of characters in each
> > > node rather than a single character, but that increases the complexit=
y
>
> > No no no no no. LINKS, please. A pointer to the segment in mallocated
> > space and its length.
>
> A detail quite irrelevant to my point. Now you're managing a linked
> list, blocks of contiguous characters, *and* the relationship between
> them to represent a single string. If the original goal is easy
> modification, I'd be dubious about how successful this design is
> compared to the simpler list of characters or block of characters.

Verbiage, Julienne, of the sort that torpedoes good ideas in
structured walkthroughs, because it is HARD to "modify" strings
maintained as what you seem to mean by "the simpler list of characters
or block of characters" (your meaning is not clear.

If you mean that strings should be maintained in the current way, if a
NUL terminated string is a "simpler" list of characters or block, then
making deletions and insertions is actually quite difficult and time-
consuming. It requires that the entire string, no matter how long, be
completely reallocated.

Whereas deletions and insertions in a linked list are always simple,
both conceptually (once you get the hang of it) and in terms of
computational complexity. It involves no excess or wasted movement of
characters.
>
> > > of the data structure, which means you're probably going to see a
> > > performance hit. Whether that hit is significant would require
> > > profiling, but even if it weren't, I'd say the benefit of a linked
> > > list is no longer clear.
>
> > My entire point was that Richard's approach is wrong. In fact, a
> > programmer with uni compsci would never have done what he did.
>
> I went home and checked my copy of the book. Personally, I think
> you're overreacting. The C Unleashed design is a viable one in that
> the data structure owns its data, as opposed to having the data owned
> by something else and merely storing pointers to said data. In the
> former case the data structure can make specific claims of correctness
> and integrity while in the latter case you can end up with dangling
> pointers and unexpected aliasing. On the down side, in the former case
> you end up copying data around when it might not be necessary, and
> making copies might not be desirable from a functionality standpoint.
>
This type of "ownership" is overrated.

If the data pointed to by the linked list is unexpectedly changed, you
most assuredly end up with what you call "dangling" pointers, and
usually a pretty obvious runtime error.

However, using Richard's solution, quite apart from its performance,
if the copied data changed, you end up in many scenarios with
what .Net authority and nice guy Dan Appleman calls the worst kind of
error...one that you don't know about.

Although corporate programmers without excess university training are
somewhat biased, in my experience, towards copying data, I'd say it's

When programmers start talk, in my experience, about "buffering" data
or making a "work file", this is often a sign of incompetence and
anxiety.

> There are advantages and disadvantages to both, which is typical in
> software design. Choose the one that best suits your needs, and you'll
> end up with higher quality software. Being dogmatic about one or the

Why is it in corporations that the most vague admonitions are used to
make irrevocable and costly decisions, whereas knowledge is equated
with dogma? This type of thinking caused the crash of two Space
Shuttles: in the case of Challenger, its engineers knew to a moral
certainty that the o-rings that failed were not tested "live" in low
temperatures, and in the case of Columbia, its engineers knew to a
moral certainty that the Space Shuttle was operating outside of its
acceptable performance bounds when it shed insulation parts on lift-
off...and this was admitted in the official review of the accident.

People died, Julienne, because vague admonitions ("think like a
manager and not an engineer") overrode hard engineering facts. As they
died in Iraq because Donald Rumsfeld's corporate BULLSHIT (which he
honed at Searle during the 1990s) overrode the hard requirements of a
respected military officer (Shinseki) for enough troops to secure
experiences at Bell Northern Research, I thank my lucky stars that I
no longer work in corporate programming.

It is *unacceptable* to copy data from a place pointed-to by a pointer
to void into a structure, and call the result "reusable software". As
I have said, preprocessor macros can be used to create a type-safe
reusable linked list manager that uses no pointers to void. However,
the real problem isn't in the use of a pointer to void. It is that the
"reusable" tool is unnecessarily copying a completely unpredictable
number of bytes.
>
> > > > Frankly, Julienne, I'm tired of the facility in which
> > > > ordinary garden-variety transform "the need to think" into "wasting
> > > > overhead" as if their brains =3D=3D their computer.
>
> > > I can't decide if you're insulting me or using my post to enable
> > > attacks on your usual clc nemeses. Either way I think I'll simply
> > > ignore it and focus on the topic at hand.
>
> > Neither. What concerns me is that in nearly all offices, a language
> > game is played that produces crumby software. Here, it's resistance to
> > good solutions which are hard for some to think about based on false
> > appeals to a misapprehension of "structured programming" and the false
> > must be an inefficient kludge".
>
> May I direct you to the irony of this statement and your resistance to

My dear Julienne, let us not simulate, even in dulcet tones, the
corporate situation in which independence thought is reduced to a bad
attitude, irrational resistance and behavior. Thank you.

> the solution from C Unleashed (which is no worse than your stated
> alternative, just different)? While I prefer not to presume to say
> *why* someone is resistant to alternatives, it often strikes me as a
> matter of ego rather than logic. In a manner of speaking: "I'd do it
> this way, so this way is right. Your way isn't how I'd do it, so your
> way is wrong".

Bullshit. There's a scene in Hamlet in which two "corporate" types,
Rosencrantz and Guildenstern, two creeps who are the Renaissance
equivalent, being courtiers, are posing as Hamlet's friends while
spying for his mortal enemy, Claudius. Hamlet, who seems "crazy" only
to the ignorant and evil characters of the play, and equally ignorant
high school English teacher, hands Guildenstern a transverse flute,
and asks him to play it. When Guildenstern says "I have not the art",
Hamlet says:

"Why looke you now, how vnworthy a thing you make of me: you would
play vpon mee; you would seeme to know my stops: you would pluck out
the heart of my Mysterie; you would sound mee from my lowest Note, to
the top of my Compasse: and there is much Mu-sicke, excellent Voice,
in this little Organe, yet cannot you make it. Why do you thinke, that
I am easier to bee  plaid on, then a Pipe? Call me what Instrument you
will, though you can fret me, you cannot play vpon me. God blesse you
Sir."

In other words, my dear Julienne, I think that of all people,
corporate data processors are amongst the least qualified to do even
Pop psychology and to start ascribing all sorts of childish and
irrational motives to programmers who don't like Richard's kind of
unprofessional crap.

>
> > And I reserve the right to answer the excessive bullying that occurs
> > in this newsgroup.
>
> I'd recommend that you take care not to cause too much collateral
> damage then. But I'm not sure that recommendation is worth the
> bandwidth from me to you because, if I recall correctly, one of your
> stated goals was to damage this newsgroup as much as possible.

That is not the case. In fact, I am usually responsible for the most
```
 0
spinoza1111 (3246)
2/17/2010 3:52:07 PM
```On 17/02/2010 13:42, spinoza1111 wrote:
> On Feb 17, 7:22 pm, Tim Streater<timstrea...@waitrose.com>  wrote:

>> What management may or may not want to do in general is neither here nor
>> there, like most of your observations. In this particular instance,
>> management wanted to invest just the right amount, but got something
>
> But it worked, you say below. My suspicion is that it became "useless"
> because you and your mates were unwilling and unable to maintain it,
> and this may be because it was crap (in which case the original
> programmer is to blame), over your heads (in which case the original
> programmer is partly to blame) or an excellent piece of code (in which
> case, you're to blame).

There was not "me and my mates". There was only me. And I had plenty
other things to do without suddenly being landed with an *unnecessarily*
complex piece of code to look after, clever or not. It was not fucking
academia where I was, it was the real world, something that you, as a
deadbeat, are unable to deal with.

>>> The guy may have been a fool. But I regard these stories as primarily
>>> myths, since in all probability you weren't any more qualified than he
>>> to tell what was needed.
>>
>> Oh, "in all probability", eh? You have evidence to support this, do you?
>> (other then your usual b/s, I mean).
>>
>> The guy was not a fool and his product worked. But the fact that it
>> needed him to make any modifications and turned into a black box once he
>> left, is proof enough that I was perfectly qualified to tell better that
>> he what was needed.
>
> That may be the case. But given what appears to me to be a VERY low
> level of skill on the part of the somewhat random selection of
> programmers who post here, the program the guy wrote may have been
> "too difficult to maintain" not as an inherent property, but because
> you were unable/unwilling to maintain it.

Of course I was unwilling to maintain it, you fool, that's the whole
point. This was someone who decided to solve the problem his own way and
fuck to everyone else. As evidenced by his disinterest in documenting it.

> His intention seems to have been to make it more easy to maintain by
> writing a sort of "conversion compiler". Sometimes such tools are more
> trouble than they are worth, because to use them you have to learn
> what some clown's ideas of what a "language for file conversion" is.

They certainly are more trouble than they're worth when there's no
fucking doccy. Thanks for noticing.

> Other times, however, corporate programmers merely have a learning
> disorder or mental block when it comes to being able to connect with
> program texts in a different style, and simply refuse to learn a
> program written in a different style or with a different approach from
> their favorite styles and approaches, for the same reason I've stated

There are certainly programmers who are unable to communicate
meaningfully. I'm not one of those.

> For the same reason they resented having to read Shakespeare in high
> school to pass a class, they resent some pretentious ponce writing
> code in an unfamiliar way. The pretentious ponce may be another
> Shakespeare, or in actuality a pretentious ponce, but more usually
> from a statistical perspective alone he's probably somewhere in
> between.

I resent a pretentious ponce giving me War and Peace when I didn't ask
for it, that's for sure. This was a small step in a longer chain, made
more complex because some selfish bastard decided to do his own thing.

> Did you in fact envy his creativity and skill? And does not the
> corporate way discourage dependence on creativity and skill?

You're making a similar mistake to that I feel is often made by
inventors, especially in this country. They say "I've invented this
widget, why is the world not beating a path to my door in admiration,
begging me to sell it to them?" The answer for them is that the
invention is 1% of the task, getting it to market is the other 99%.
Similarly you seem to feel that creativity and skill are all that
counts. These are important but not the be-all and end-all. A
willingness to see the bigger picture, and to know when to subsume your
"creativity" and do something duller that fits better, are also
important. You seem to lack this ability.

And no, I had no "envy of his skills/creativity". I've worked with
people who've written actual compilers, so I know who is worth admiring
for their skill.

> If there was only one good way to convert the file, then the guy was
> either a pretentious ponce or overqualified. If however he saw
> something you did not, then he was a "genius". The truth is probably
> somewhere in between.

Not a genius. Just not managed very well.

>> earthquake like they had would be buggered, US Corps or not.
>
> No again. Again, the San Francisco Bay area had a Richter 7.0 scale
> earthquake at the start of the World Series in 1989, and casualties
> and damage were minimal.

Well, I know all about that earthquake too; I was there at the time. The
only time in my life when I didn't have dialtone.

--
Tim

"That the freedom of speech and debates or proceedings in Parliament
ought not to be impeached or questioned in any court or place out of
Parliament"

Bill of Rights 1689
```
 0
timstreater (945)
2/17/2010 4:48:59 PM
```On 2010-02-17, Nick Keighley <nick_keighley_nospam@hotmail.com> wrote:
> why so insistent? Whats wrong with variable sized nodes?

Hard to reuse and quite likely to end up in different malloc pools.

As I recall, mbufs use a static-size node, but indicate how many octets
are currently in it.  The nodes can thus live in a pool and be shuffled
and reused as needed.  If you pick a "reasonable" size -- one such that
you don't waste too much space on short strings, or need too many links
for normal-sized strings -- that can be very efficient, especially because
it makes allocating and freeing nodes EXTREMELY cheap.  (You just shove
them back on the "list of free nodes", etcetera.)

-s
--
Copyright 2010, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
```
 0
usenet-nospam (2309)
2/17/2010 5:02:54 PM
```On Feb 17, 7:02=A0pm, Seebs <usenet-nos...@seebs.net> wrote:
> On 2010-02-17, Nick Keighley <nick_keighley_nos...@hotmail.com> wrote:
>
> > why so insistent? Whats wrong with variable sized nodes?
>
> Hard to reuse and quite likely to end up in different malloc pools.
>
> As I recall, mbufs use a static-size node, but indicate how many octets
> are currently in it. =A0The nodes can thus live in a pool and be shuffled
> and reused as needed. =A0If you pick a "reasonable" size -- one such that
> you don't waste too much space on short strings, or need too many links
> for normal-sized strings -- that can be very efficient, especially becaus=
e
> it makes allocating and freeing nodes EXTREMELY cheap. =A0(You just shove
> them back on the "list of free nodes", etcetera.)
>
There's code to do this on my website

http://www.personal.leeds.ac.uk/~bgy1mm

It's in the Basic Algorithms supporting webpages, under "Memory
Games".

```
 0
2/17/2010 6:44:54 PM
```Malcolm McLean wrote:
> On Feb 17, 2:08 am, spinoza1111 <spinoza1...@yahoo.com> wrote:
>> A 7.0
>> earthquake in San Francisco in 1989 at the start of the World Series
>> killed only a few dozen people and destroyed no major structures,
>> because Californians HAD THE MONEY to build earthquake safe:
>>
> You are absolutely right. Few if any Haitians died by act of God, but
> because humans chose to build unstable structures, knowing that
> earthquakes occasionally happen.
>
> To put this back on topic, what's a professional Haitian architect to
> do?

I still think you're a little way off...

--
Bartc
```
 0
bartc (786)
2/17/2010 9:50:28 PM
```"spinoza1111" <spinoza1111@yahoo.com> wrote in message
On Feb 16, 5:31 pm, "Chris M. Thomasson" <n...@spam.invalid> wrote:
[...]
> > > > I don't know why Richard implemented a simple linked-list that way.
> > > > I
> > > > take
> > > > it he is not that fond of intrusive linked lists.
> > > But his solution IS intrusive, unless by "intrusive" you mean
> > > something else.
> >
> > I mean why not embed the list node directly into a data-structure? The
> > list
> > nodes intrudes into the object.
[...]
> > > > What about intrusive data-structures that do not require any copying
> > > > and/or
> > > > void pointers? I use them all the time.
> > > That was my idea...use a macro for strong typing.
> >
> > I was thinking of the following technique. Here, let me quickly code up
> > a
> > simple example:
> > _______________________________________________________________
[...]
> > _______________________________________________________________
> >
> > The `struct slist' objects intrude upon the `struct foo' objects. Now,
> > you
> > can create a generic set of functions that operate on `struct slist'
> > objects
> > regardless of what they are embedded within (e.g., see the `slreverse()'
> > function).
>
> Very clever. I like this idea. Lists remain pure lists. Very elegant.
> But: I do not understand how, if I have ONLY a foo, to find the next
> foo.

Here is a more advanced example:
________________________________________________________________
#include <stdio.h>
#include <stddef.h>

#define CONTAINS_EX(mp_self, mp_type, mp_offset) \
((mp_type*)(((unsigned char*)(mp_self)) - (mp_offset)))

#define CONTAINS(mp_self, mp_type, mp_member) \
CONTAINS_EX(mp_self, mp_type, offsetof(mp_type, mp_member))

#define CONTAINS_OFFSET(mp_self, mp_tptr) \
((size_t)(((unsigned char*)(mp_tptr)) - \
((unsigned char*)(mp_self))))

struct slist
{
struct slist* next;
};

#define SLIST_SINIT { NULL }

void
slpush(struct slist* const self,
struct slist* node)
{
node->next = self->next;
self->next = node;
}

struct slist*
slpop(struct slist* const self)
{
struct slist* node = self->next;
if (node) self->next = node->next;
return node;
}

void
slreverse(struct slist* const self)
{
struct slist* node = self->next;

while (node)
{
struct slist* next = node->next;
node = next;
}

}

struct foo
{
char const* string;
struct slist node1;
struct slist node2;
};

#define FOO_SINIT(mp_string) \
{ (mp_string), SLIST_SINIT, SLIST_SINIT }

void
foo_output_from(struct foo const* const self,
struct slist* node,
FILE* output)
{
struct slist const* cur;
size_t offset = CONTAINS_OFFSET(self, node);

for (cur = node; cur; cur = cur->next)
{
struct foo const* f =
CONTAINS_EX(cur, struct foo, offset);

fprintf(output,
"(%p)->struct foo(%s)\n",
(void*)f,
f->string);
}

fputs("---------------------------------------------\n",
output);
}

int main()
{
struct slist list1 = SLIST_SINIT;
struct slist list2 = SLIST_SINIT;

struct foo foo[] =
{
FOO_SINIT("One"),   FOO_SINIT("Two"),
FOO_SINIT("Three"), FOO_SINIT("Four"),
FOO_SINIT("Five"),  FOO_SINIT("Six"),
FOO_SINIT("Seven"), FOO_SINIT("Eight"),
FOO_SINIT("Nine"),  FOO_SINIT("Ten")
};

size_t i;
size_t depth = sizeof(foo) / sizeof(foo[0]);

for (i = 0; i < depth; ++i)
{
slpush(&list1, &foo[i].node1);
slpush(&list2, &foo[i].node2);
}

slreverse(&list2);

for (i = 0; i < depth; ++i)
{
foo_output_from(foo + i, &foo[i].node1, stdout);
foo_output_from(foo + i, &foo[i].node2, stdout);
}

return 0;
}
________________________________________________________________

Pay close attention to the `foo_output_from()' procedure. I pass it a
pointer to a `struct foo', a pointer to a node within said `struct foo', and
a pointer to a file stream. First it needs to calculate an offset into a
`struct foo' so that it can extract them from `struct slist' objects. Once
it has the offset, it simply iterates the list starting at the node. Of
course this is a much more complicated example. I expect most usage cases
will simply involve:
________________________________________________________________
struct foo
{
struct slist node;
/* [whatever] */
};
________________________________________________________________

Now, one can avoid all the `CONTAINS' macros and just cast `struct slist'
directly into `struct foo'. That's much simpler indeed!

;^)

```
 0
no6 (2828)
2/17/2010 10:36:27 PM
```On Feb 17, 10:52=A0am, spinoza1111 <spinoza1...@yahoo.com> wrote:
> On Feb 17, 10:07=A0pm, Julienne Walker <happyfro...@hotmail.com> wrote:
> > On Feb 16, 7:22=A0pm,spinoza1111<spinoza1...@yahoo.com> wrote:
>
> > > On Feb 16, 9:59=A0pm, Julienne Walker <happyfro...@hotmail.com> wrote=
:
> > > > On Feb 16, 2:28=A0am,spinoza1111<spinoza1...@yahoo.com> wrote:
>
> > > > One can alleviate that waste by storing arrays of characters in eac=
h
> > > > node rather than a single character, but that increases the complex=
ity
>
> > > No no no no no. LINKS, please. A pointer to the segment in mallocated
> > > space and its length.
>
> > A detail quite irrelevant to my point. Now you're managing a linked
> > list, blocks of contiguous characters, *and* the relationship between
> > them to represent a single string. If the original goal is easy
> > modification, I'd be dubious about how successful this design is
> > compared to the simpler list of characters or block of characters.
>
> Verbiage, Julienne, of the sort that torpedoes good ideas in
> structured walkthroughs, because it is HARD to "modify" strings
> maintained as what you seem to mean by "the simpler list of characters
> or block of characters" (your meaning is not clear.

I'm afraid I can't imagine how my meaning couldn't be clear: A linked
list of characters or an "array" of characters. These are one-
dimensional data structures, completely linear in concept, and easy to
visualize even for the most remedial of comp sci students. Combining
them adds complexity and relatively difficult design decisions.

> If you mean that strings should be maintained in the current way, if a
> NUL terminated string is a "simpler" list of characters or block, then
> making deletions and insertions is actually quite difficult and time-
> consuming. It requires that the entire string, no matter how long, be
> completely reallocated.

As for reallocation, that really depends on the current capacity and
your needs. Insertion wouldn't require reallocation if the blocks
capacity is already large enough. Deletion would only require
reallocation if you want to trim unused memory. If strings were
immutable, it might be a different story, but that's not the case in
C.

> Whereas deletions and insertions in a linked list are always simple,
> both conceptually (once you get the hang of it) and in terms of
> computational complexity. It involves no excess or wasted movement of
> characters.

Agreed. But let's not forget that you have more than just the link
surgery of a linked list. Consider the following data structure you
described. Each node is a pointer to a block of characters:

"this" -> "is" -> "a" -> "test"

If this string representation were to be useful at all, you'd need to
support deleting parts of each block (such as the "hi" from "this")
and inserting inside each block. I have a hard time believing how this
could easily involve excess or wasted movement of characters.

There's nothing wrong with the data structure if it's what you need
(I've written lists like this before), but I'm not buying your
hype. ;-)

> > > > of the data structure, which means you're probably going to see a
> > > > performance hit. Whether that hit is significant would require
> > > > profiling, but even if it weren't, I'd say the benefit of a linked
> > > > list is no longer clear.
>
> > > My entire point was that Richard's approach is wrong. In fact, a
> > > programmer with uni compsci would never have done what he did.
>
> > I went home and checked my copy of the book. Personally, I think
> > you're overreacting. The C Unleashed design is a viable one in that
> > the data structure owns its data, as opposed to having the data owned
> > by something else and merely storing pointers to said data. In the
> > former case the data structure can make specific claims of correctness
> > and integrity while in the latter case you can end up with dangling
> > pointers and unexpected aliasing. On the down side, in the former case
> > you end up copying data around when it might not be necessary, and
> > making copies might not be desirable from a functionality standpoint.
>
> This type of "ownership" is overrated.

> However, using Richard's solution, quite apart from its performance,
> if the copied data changed, you end up in many scenarios with
> what .Net authority and nice guy Dan Appleman calls the worst kind of
> error...one that you don't know about.

Scenarios such as what?

> Although corporate programmers without excess university training are
> somewhat biased, in my experience, towards copying data, I'd say it's
> usually better given my compiler experience in addition to my business
> experience to link to it.

"Usually better" may indeed be the case in your experience. In my
experience, linking vs. copying is situational. Now we're entering the
realm of objectivity, which is a good thing. Opinions are clearly
stated as opinion, and words are carefully chosen so as to avoid
making absolute statements.

> > There are advantages and disadvantages to both, which is typical in
> > software design. Choose the one that best suits your needs, and you'll
> > end up with higher quality software. Being dogmatic about one or the
> > other limits your options.
>
> Why is it in corporations that the most vague admonitions are used to
> make irrevocable and costly decisions, whereas knowledge is equated
> with dogma?

Failure to apply the full extent of knowledge is equated with dogma.
I'd find it laughable if you weren't aware of the advantages of
statements clearly make it appear as if copying data has no advantages
we were actually trying to make a decision, I'd be forcing you to
consider all of the alternatives I could think of so that the best

> > > > > Frankly, Julienne, I'm tired of the facility in which
> > > > > ordinary garden-variety transform "the need to think" into "wasti=
ng
> > > > > overhead" as if their brains =3D=3D their computer.
>
> > > > I can't decide if you're insulting me or using my post to enable
> > > > attacks on your usual clc nemeses. Either way I think I'll simply
> > > > ignore it and focus on the topic at hand.
>
> > > Neither. What concerns me is that in nearly all offices, a language
> > > game is played that produces crumby software. Here, it's resistance t=
o
> > > good solutions which are hard for some to think about based on false
> > > appeals to a misapprehension of "structured programming" and the fals=
e
> > > must be an inefficient kludge".
>
> > May I direct you to the irony of this statement and your resistance to
>
> My dear Julienne, let us not simulate, even in dulcet tones, the
> corporate situation in which independence thought is reduced to a bad
> attitude, irrational resistance and behavior. Thank you.

Hmm, so you're allowed to defend yourself against bullying yet I'm
not? Your attitude toward me has been hostile despite perfectly civil
discourse on my end. I feel I've been intentionally insulted several
times, and the instant I mention your hypocricy, *you're* the victim?
Sorry, Mr. Nilges, but I cry bullshit. I'm neither stupid nor
ignorant, and if you truly want to discuss technical issues, I expect
you to treat me with at least a modicum of respect.

> > > And I reserve the right to answer the excessive bullying that occurs
> > > in this newsgroup.
>
> > I'd recommend that you take care not to cause too much collateral
> > damage then. But I'm not sure that recommendation is worth the
> > bandwidth from me to you because, if I recall correctly, one of your
> > stated goals was to damage this newsgroup as much as possible.
>
> That is not the case. In fact, I am usually responsible for the most

You're also one of the most vocal participants in flame wars.
```
 0
2/18/2010 12:53:19 AM
```On Feb 18, 12:48=A0am, Tim Streater <timstrea...@waitrose.com> wrote:
> On 17/02/2010 13:42,spinoza1111wrote:
>
> > On Feb 17, 7:22 pm, Tim Streater<timstrea...@waitrose.com> =A0wrote:
> >> What management may or may not want to do in general is neither here n=
or
> >> there, like most of your observations. In this particular instance,
> >> management wanted to invest just the right amount, but got something
t.
>
> > But it worked, you say below. My suspicion is that it became "useless"
> > because you and your mates were unwilling and unable to maintain it,
> > and this may be because it was crap (in which case the original
> > programmer is to blame), over your heads (in which case the original
> > programmer is partly to blame) or an excellent piece of code (in which
> > case, you're to blame).
>
> There was not "me and my mates". There was only me. And I had plenty
> other things to do without suddenly being landed with an *unnecessarily*
> complex piece of code to look after, clever or not. It was not fucking
> academia where I was, it was the real world, something that you, as a
> deadbeat, are unable to deal with.

I don't work in fucking academia. But why is the corporation "the real
world"? Why is it any more real than anything else? I found that most
corporate jobs in data processing are a fantasy and welfare for white
males, since it's too risky for management to do anything. Is this
reality?
>
>
>
>
>
> >>> The guy may have been a fool. But I regard these stories as primarily
> >>> myths, since in all probability you weren't any more qualified than h=
e
> >>> to tell what was needed.
>
> >> Oh, "in all probability", eh? You have evidence to support this, do yo=
u?
> >> (other then your usual b/s, I mean).
>
> >> The guy was not a fool and his product worked. But the fact that it
> >> needed him to make any modifications and turned into a black box once =
he
> >> left, is proof enough that I was perfectly qualified to tell better th=
at
> >> he what was needed.
>
> > That may be the case. But given what appears to me to be a VERY low
> > level of skill on the part of the somewhat random selection of
> > programmers who post here, the program the guy wrote may have been
> > "too difficult to maintain" not as an inherent property, but because
> > you were unable/unwilling to maintain it.
>
> Of course I was unwilling to maintain it, you fool, that's the whole
> point. This was someone who decided to solve the problem his own way and
> fuck to everyone else. As evidenced by his disinterest in documenting it.

Maybe he just didn't want to work with somebody with a foul mouth and
>
> > His intention seems to have been to make it more easy to maintain by
> > writing a sort of "conversion compiler". Sometimes such tools are more
> > trouble than they are worth, because to use them you have to learn
> > what some clown's ideas of what a "language for file conversion" is.
>
> They certainly are more trouble than they're worth when there's no
> fucking doccy. Thanks for noticing.
>
> > Other times, however, corporate programmers merely have a learning
> > disorder or mental block when it comes to being able to connect with
> > program texts in a different style, and simply refuse to learn a
> > program written in a different style or with a different approach from
> > their favorite styles and approaches, for the same reason I've stated
>
> There are certainly programmers who are unable to communicate
> meaningfully. I'm not one of those.

You've given no evidence here.
>
> > For the same reason they resented having to read Shakespeare in high
> > school to pass a class, they resent some pretentious ponce writing
> > code in an unfamiliar way. The pretentious ponce may be another
> > Shakespeare, or in actuality a pretentious ponce, but more usually
> > from a statistical perspective alone he's probably somewhere in
> > between.
>
> I resent a pretentious ponce giving me War and Peace when I didn't ask
> for it, that's for sure. This was a small step in a longer chain, made
> more complex because some selfish bastard decided to do his own thing.
>
> > Did you in fact envy his creativity and skill? And does not the
> > corporate way discourage dependence on creativity and skill?
>
> You're making a similar mistake to that I feel is often made by
> inventors, especially in this country. They say "I've invented this
> widget, why is the world not beating a path to my door in admiration,
> begging me to sell it to them?" The answer for them is that the
> invention is 1% of the task, getting it to market is the other 99%.
> Similarly you seem to feel that creativity and skill are all that
> counts. These are important but not the be-all and end-all. A
> willingness to see the bigger picture, and to know when to subsume your
> "creativity" and do something duller that fits better, are also
> important. You seem to lack this ability.

zzzz....

Actually, this isn't true. The people who "subsume their creativity"
and "do something duller that fits better", in my experience, are
simply employees until laid off, retired or dead.

>
> And no, I had no "envy of his skills/creativity". I've worked with
> people who've written actual compilers, so I know who is worth admiring
> for their skill.

Wow, actual compilers. As opposed to mythical compilers?
>
> > If there was only one good way to convert the file, then the guy was
> > either a pretentious ponce or overqualified. If however he saw
> > something you did not, then he was a "genius". The truth is probably
> > somewhere in between.
>
> Not a genius. Just not managed very well.
>
> >> earthquake like they had would be buggered, US Corps or not.
>
> > No again. Again, the San Francisco Bay area had a Richter 7.0 scale
> > earthquake at the start of the World Series in 1989, and casualties
> > and damage were minimal.
>
> Well, I know all about that earthquake too; I was there at the time. The
> only time in my life when I didn't have dialtone.
>
> --
> Tim
>
> "That the freedom of speech and debates or proceedings in Parliament
> ought not to be impeached or questioned in any court or place out of
> Parliament"
>
> Bill of Rights 1689

```
 0
spinoza1111 (3246)
2/18/2010 2:15:29 AM
```On Feb 18, 8:53=A0am, Julienne Walker <happyfro...@hotmail.com> wrote:
> On Feb 17, 10:52=A0am,spinoza1111<spinoza1...@yahoo.com> wrote:
>
>
>
>
>
> > On Feb 17, 10:07=A0pm, Julienne Walker <happyfro...@hotmail.com> wrote:
> > > On Feb 16, 7:22=A0pm,spinoza1111<spinoza1...@yahoo.com> wrote:
>
> > > > On Feb 16, 9:59=A0pm, Julienne Walker <happyfro...@hotmail.com> wro=
te:
> > > > > On Feb 16, 2:28=A0am,spinoza1111<spinoza1...@yahoo.com> wrote:
>
> > > > > One can alleviate that waste by storing arrays of characters in e=
ach
> > > > > node rather than a single character, but that increases the compl=
exity
>
> > > > No no no no no. LINKS, please. A pointer to the segment in mallocat=
ed
> > > > space and its length.
>
> > > A detail quite irrelevant to my point. Now you're managing a linked
> > > list, blocks of contiguous characters, *and* the relationship between
> > > them to represent a single string. If the original goal is easy
> > > modification, I'd be dubious about how successful this design is
> > > compared to the simpler list of characters or block of characters.
>
> > Verbiage, Julienne, of the sort that torpedoes good ideas in
> > structured walkthroughs, because it is HARD to "modify" strings
> > maintained as what you seem to mean by "the simpler list of characters
> > or block of characters" (your meaning is not clear.
>
> I'm afraid I can't imagine how my meaning couldn't be clear: A linked
> list of characters or an "array" of characters. These are one-
> dimensional data structures, completely linear in concept, and easy to
> visualize even for the most remedial of comp sci students. Combining
> them adds complexity and relatively difficult design decisions.

No, "a linked list of string segments" solves our problem. You do wish
to solve the problem, don't you?

>
> > If you mean that strings should be maintained in the current way, if a
> > NUL terminated string is a "simpler" list of characters or block, then
> > making deletions and insertions is actually quite difficult and time-
> > consuming. It requires that the entire string, no matter how long, be
> > completely reallocated.
>
> As for reallocation, that really depends on the current capacity and
> your needs. Insertion wouldn't require reallocation if the blocks
> capacity is already large enough

How do you know this?

>. Deletion would only require
> reallocation if you want to trim unused memory. If strings were
> immutable, it might be a different story, but that's not the case in
> C.
>
> > Whereas deletions and insertions in a linked list are always simple,
> > both conceptually (once you get the hang of it) and in terms of
> > computational complexity. It involves no excess or wasted movement of
> > characters.
>
> Agreed. But let's not forget that you have more than just the link
> surgery of a linked list. Consider the following data structure you
> described. Each node is a pointer to a block of characters:
>
> "this" -> "is" -> "a" -> "test"
>
> If this string representation were to be useful at all, you'd need to
> support deleting parts of each block (such as the "hi" from "this")
> and inserting inside each block. I have a hard time believing how this
> could easily involve excess or wasted movement of characters.

You have a hard time believing how this doesn't add complexity because
you haven't done this type of work, can be my only conclusion here.
This is mental complexity not "complexity".

>
> There's nothing wrong with the data structure if it's what you need
> (I've written lists like this before), but I'm not buying your
> hype. ;-)

Hype? What's insane here is that I have no reason to "hype" anything
as I would in a real job, yet you insist on creating a corporate style
situation here because, apparently, you can't think outside the
corporate box.

>
>
>
>
>
> > > > > of the data structure, which means you're probably going to see a
> > > > > performance hit. Whether that hit is significant would require
> > > > > profiling, but even if it weren't, I'd say the benefit of a linke=
d
> > > > > list is no longer clear.
>
> > > > My entire point was that Richard's approach is wrong. In fact, a
> > > > programmer with uni compsci would never have done what he did.
>
> > > I went home and checked my copy of the book. Personally, I think
> > > you're overreacting. The C Unleashed design is a viable one in that
> > > the data structure owns its data, as opposed to having the data owned
> > > by something else and merely storing pointers to said data. In the
> > > former case the data structure can make specific claims of correctnes=
s
> > > and integrity while in the latter case you can end up with dangling
> > > pointers and unexpected aliasing. On the down side, in the former cas=
e
> > > you end up copying data around when it might not be necessary, and
> > > making copies might not be desirable from a functionality standpoint.
>
> > This type of "ownership" is overrated.
>

It is purely psychological. You're insecure with my solution because I
am not in authority over you, whereas Richard is a bully who always
wants to get his way, and women have a tendency to defer to bullying.
He has a sort of "virtual" authority. But the fact remains that his
code shows no evidence of education or skill in this matter.

>
> > However, using Richard's solution, quite apart from its performance,
> > if the copied data changed, you end up in many scenarios with
> > what .Net authority and nice guy Dan Appleman calls the worst kind of
> > error...one that you don't know about.
>
> Scenarios such as what?

Richard's code is using the copy in the linked list but the original
data is changed.

>
> > Although corporate programmers without excess university training are
> > somewhat biased, in my experience, towards copying data, I'd say it's
> > usually better given my compiler experience in addition to my business
> > experience to link to it.
>
> "Usually better" may indeed be the case in your experience. In my
> experience, linking vs. copying is situational. Now we're entering the
> realm of objectivity, which is a good thing. Opinions are clearly
> stated as opinion, and words are carefully chosen so as to avoid
> making absolute statements.

Such as "oh, I think you should think like a manager and not an
engineer?" Or "in my opinion, the fact that no insulation piece has
been, so far, has caused any damage means it's not a problem". Or, "in
my opinion, General Shinseki, you're asking for too many troops?" Or,
"in my opinion, Saddam Hussein has WMDs".

Those are four opinions which got people killed.

>
> > > There are advantages and disadvantages to both, which is typical in
> > > software design. Choose the one that best suits your needs, and you'l=
l
> > > end up with higher quality software. Being dogmatic about one or the
> > > other limits your options.
>
> > Why is it in corporations that the most vague admonitions are used to
> > make irrevocable and costly decisions, whereas knowledge is equated
> > with dogma?
>
> Failure to apply the full extent of knowledge is equated with dogma.
> I'd find it laughable if you weren't aware of the advantages of
> statements clearly make it appear as if copying data has no advantages
> we were actually trying to make a decision, I'd be forcing you to
> consider all of the alternatives I could think of so that the best
> possible decision could be made.

Which at this point is your decision, because that's the shitty little
corporate game: My Way. Well, I don't have to play it.

There is, in fact, no downside to a correctly implemented linked list
of pointers, whereas there IS a considerable downside, which you don't
seem to understand, to a correctly implemented link list of copied
data. I've shown you, but shall repeat: Richard Heathfield's reusable
tool will blow up, performance-wise, if passed large nodes. It also
creates a copy of data which has to be maintained in parallel with the
original.

>
>
>
>
>
> > > > > > Frankly, Julienne, I'm tired of the facility in which
> > > > > > ordinary garden-variety transform "the need to think" into "was=
ting
> > > > > > overhead" as if their brains =3D=3D their computer.
>
> > > > > I can't decide if you're insulting me or using my post to enable
> > > > > attacks on your usual clc nemeses. Either way I think I'll simply
> > > > > ignore it and focus on the topic at hand.
>
> > > > Neither. What concerns me is that in nearly all offices, a language
> > > > game is played that produces crumby software. Here, it's resistance=
to
> > > > good solutions which are hard for some to think about based on fals=
e
> > > > appeals to a misapprehension of "structured programming" and the fa=
lse
> > > > inference from "it is difficult for me to think about this" to "thi=
s
> > > > must be an inefficient kludge".
>
> > > May I direct you to the irony of this statement and your resistance t=
o
>
> > My dear Julienne, let us not simulate, even in dulcet tones, the
> > corporate situation in which independence thought is reduced to a bad
> > attitude, irrational resistance and behavior. Thank you.
>
> Hmm, so you're allowed to defend yourself against bullying yet I'm
> not?

I'm not bullying you.

> Your attitude toward me has been hostile despite perfectly civil

If disagreement is hostility, then who's hostile?

> discourse on my end. I feel I've been intentionally insulted several
> times, and the instant I mention your hypocricy, *you're* the victim?
> Sorry, Mr. Nilges, but I cry bullshit. I'm neither stupid nor
> ignorant, and if you truly want to discuss technical issues, I expect
> you to treat me with at least a modicum of respect.

By agreeing with you, or even better, seeming to in the accepted,
corporate mold, and then going off and doing whatever needed to be
done. Sorry, I don't have to play that game here, and I won't.

>
> > > > And I reserve the right to answer the excessive bullying that occur=
s
> > > > in this newsgroup.
>
> > > I'd recommend that you take care not to cause too much collateral
> > > damage then. But I'm not sure that recommendation is worth the
> > > bandwidth from me to you because, if I recall correctly, one of your
> > > stated goals was to damage this newsgroup as much as possible.
>
> > That is not the case. In fact, I am usually responsible for the most
> > interesting and well-attended threads.
>
> You're also one of the most vocal participants in flame wars.

No, I'm frequently bullied because I attract notice and then envy,
because I am both literate and a great programmer (for let us not
speak falsely now the hour is much too late). And unlike most women in
this situation, I fight back being a guy.
```
 0
spinoza1111 (3246)
2/18/2010 2:36:22 AM
```spinoza1111 wrote:
> On Feb 18, 12:48 am, Tim Streater <timstrea...@waitrose.com> wrote:

<prior nonsense snipped>

>> There are certainly programmers who are unable to communicate
>> meaningfully. I'm not one of those.
>
> You've given no evidence here.

It is ironic that you, who almost never support your own claims with
hard facts, should ask for someone else to provide evidence. It is the
height of hypocrisy.

Nevertheless, Tim Streater is not you, and it is not unreasonable to
expect some evidence to exist for his claims (unlike yours). I can
provide some. (It won't convince *you*, obviously, but that doesn't
bother me in the slightest.)

I have been reading Tim Streater's articles for some time now. I have
occasionally participated in discussions with him. In those discussions,
I have never had any cause whatsoever to doubt his ability to
communicate meaningfully. Anyone who wishes to assure themselves of his
ability to communicate meaningfully need only pick a dozen samples of
his articles at random, and read through them. (And anyone who wishes to
discern whether his correspondent can communicate meaningfully need only
do the same to /his/ articles.)

<subsequent nonsense snipped>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
```
 0
rjh (10791)
2/18/2010 6:40:04 AM
```Richard Heathfield <rjh@see.sig.invalid> writes:
> spinoza1111 wrote:
>> On Feb 18, 12:48 am, Tim Streater <timstrea...@waitrose.com> wrote:
>
> <prior nonsense snipped>
>
>>> There are certainly programmers who are unable to communicate
>>> meaningfully. I'm not one of those.
>>
>> You've given no evidence here.
>
> It is ironic that you, who almost never support your own claims with
> hard facts, should ask for someone else to provide evidence. It is the
> height of hypocrisy.
[snip]
> <subsequent nonsense snipped>

Yes, spinoza1111 is wrong again, and on a topic having nothing
to do either with C or with the supposed subject of this thread.
Is pointing it out really a good use of time and bandwidth?

--
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
```
 0
kst-u (21963)
2/18/2010 8:15:14 AM
```On Feb 18, 2:53=A0am, Julienne Walker <happyfro...@hotmail.com> wrote:
>
> I'm afraid I can't imagine how my meaning couldn't be clear: A linked
> list of characters or an "array" of characters. These are one-
> dimensional data structures, completely linear in concept, and easy to
> visualize even for the most remedial of comp sci students. Combining
> them adds complexity and relatively difficult design decisions.
>
I'm working on DNA data at the moment. Currently I store it as
conventional strings.

However the data is a long list of ACGTs. A human can't possibly read
it all, even small sections look meaningless after a bit. The eye is
drawn to repeats and chance combinations like 'TAGACAT'.
However genomes are not unstructured. Different areas have different
statistical characteristics, though we don't know exactly what that
means. My job, basically, is to take the raw strings and turn them
into something else, something that humans can talk about in a
sensible way.
So I will need to build extra layers of structure on top of the
strings.

```
 0
2/18/2010 8:55:15 AM
```Keith Thompson wrote:
> Richard Heathfield <rjh@see.sig.invalid> writes:
>> spinoza1111 wrote:
>>> On Feb 18, 12:48 am, Tim Streater <timstrea...@waitrose.com> wrote:
>> <prior nonsense snipped>
>>
>>>> There are certainly programmers who are unable to communicate
>>>> meaningfully. I'm not one of those.
>>> You've given no evidence here.
>> It is ironic that you, who almost never support your own claims with
>> hard facts, should ask for someone else to provide evidence. It is the
>> height of hypocrisy.
> [snip]
>> <subsequent nonsense snipped>
>
> Yes, spinoza1111 is wrong again, and on a topic having nothing
> to do either with C or with the supposed subject of this thread.
> Is pointing it out really a good use of time and bandwidth?

Put it this way - although I haven't measured it, I would estimate that
the number of his errors that I actually address is significantly under
1% of the total errors he posts. (If I were to attempt to address every
error he makes, (a) I wouldn't ever get any real work done, and (b) I'd
be plonked by most of this group's subscribers.)

So it could be a lot worse. On the other hand, I acknowledge that it
could be better.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
```
 0
rjh (10791)
2/18/2010 9:22:26 AM
```On 18 Feb, 08:55, Malcolm McLean <malcolm.mcle...@btinternet.com>
wrote:
> On Feb 18, 2:53=A0am, Julienne Walker <happyfro...@hotmail.com> wrote:
>
> > I'm afraid I can't imagine how my meaning couldn't be clear: A linked
> > list of characters or an "array" of characters. These are one-
> > dimensional data structures, completely linear in concept, and easy to
> > visualize even for the most remedial of comp sci students. Combining
> > them adds complexity and relatively difficult design decisions.
>
> I'm working on DNA data at the moment. Currently I store it as
> conventional strings.
>
> However the data is a long list of ACGTs. A human can't possibly read
> it all, even small sections look meaningless after a bit. The eye is
> drawn to repeats and chance combinations like 'TAGACAT'.
> However genomes are not unstructured. Different areas have different
> statistical characteristics, though we don't know exactly what that
> means. My job, basically, is to take the raw strings and turn them
> into something else, something that humans can talk about in a
> sensible way.
> So I will need to build extra layers of structure on top of the
> strings.

are you agreeing or disagreeing?
```
 0
2/18/2010 9:31:36 AM
```Nick Keighley wrote:
> On 18 Feb, 08:55, Malcolm McLean <malcolm.mcle...@btinternet.com>
> wrote:
>> On Feb 18, 2:53 am, Julienne Walker <happyfro...@hotmail.com> wrote:
>>
>>> I'm afraid I can't imagine how my meaning couldn't be clear: A linked
>>> list of characters or an "array" of characters. These are one-
>>> dimensional data structures, completely linear in concept, and easy to
>>> visualize even for the most remedial of comp sci students. Combining
>>> them adds complexity and relatively difficult design decisions.
>> I'm working on DNA data at the moment. Currently I store it as
>> conventional strings.
>>
>> However the data is a long list of ACGTs. A human can't possibly read
>> it all, even small sections look meaningless after a bit. The eye is
>> drawn to repeats and chance combinations like 'TAGACAT'.
>> However genomes are not unstructured. Different areas have different
>> statistical characteristics, though we don't know exactly what that
>> means. My job, basically, is to take the raw strings and turn them
>> into something else, something that humans can talk about in a
>> sensible way.
>> So I will need to build extra layers of structure on top of the
>> strings.
>
> are you agreeing or disagreeing?

No, I don't think so.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
```
 0
rjh (10791)
2/18/2010 9:37:27 AM
```On Feb 18, 5:22=A0pm, Richard Heathfield <r...@see.sig.invalid> wrote:
> Keith Thompson wrote:
> > Richard Heathfield <r...@see.sig.invalid> writes:
> >>spinoza1111wrote:
> >>> On Feb 18, 12:48 am, Tim Streater <timstrea...@waitrose.com> wrote:
> >> <prior nonsense snipped>
>
> >>>> There are certainly programmers who are unable to communicate
> >>>> meaningfully. I'm not one of those.
> >>> You've given no evidence here.
> >> It is ironic that you, who almost never support your own claims with
> >> hard facts, should ask for someone else to provide evidence. It is the
> >> height of hypocrisy.
> > [snip]
> >> <subsequent nonsense snipped>
>
> > Yes,spinoza1111is wrong again, and on a topic having nothing
> > to do either with C or with the supposed subject of this thread.
> > Is pointing it out really a good use of time and bandwidth?
>
> Put it this way - although I haven't measured it, I would estimate that
> the number of his errors that I actually address is significantly under
> 1% of the total errors he posts. (If I were to attempt to address every
> error he makes, (a) I wouldn't ever get any real work done, and (b) I'd
> be plonked by most of this group's subscribers.)

You're lying. You put matters of opinion under "errors" to get the
result you want, the impression that like you and Seebach, I'm
incompetent, using media in the Fascist way to create a blurred
that puts data in nodes using a void pointer instead of using the
preprocessor for strong typing and pointers in nodes (a very serious
error), and Seebach can't get strlen right without an off by one bug
(low comedy). Whereas my biggest "error" is having more education and
culture than you while being much better as a programmer, which means
you've wasted too much time learning your trade. This is why you bully
and enable bullying here. It's the only place you can get a forum
where people will listen to you.

>
> So it could be a lot worse. On the other hand, I acknowledge that it
> could be better.
>
> --
> Richard Heathfield <http://www.cpax.org.uk>
> Email: -http://www. +rjh@
> "Usenet is a strange place" - dmr 29 July 1999
> Sig line vacant - apply within

```
 0
spinoza1111 (3246)
2/18/2010 12:03:06 PM
```On Feb 18, 4:55=A0pm, Malcolm McLean <malcolm.mcle...@btinternet.com>
wrote:
> On Feb 18, 2:53=A0am, Julienne Walker <happyfro...@hotmail.com> wrote:
>
> > I'm afraid I can't imagine how my meaning couldn't be clear: A linked
> > list of characters or an "array" of characters. These are one-
> > dimensional data structures, completely linear in concept, and easy to
> > visualize even for the most remedial of comp sci students. Combining
> > them adds complexity and relatively difficult design decisions.
>
> I'm working on DNA data at the moment. Currently I store it as
> conventional strings.
>
> However the data is a long list of ACGTs. A human can't possibly read
> it all, even small sections look meaningless after a bit. The eye is
> drawn to repeats and chance combinations like 'TAGACAT'.
> However genomes are not unstructured. Different areas have different
> statistical characteristics, though we don't know exactly what that
> means. My job, basically, is to take the raw strings and turn them
> into something else, something that humans can talk about in a
> sensible way.
> So I will need to build extra layers of structure on top of the
> strings.

In other words, complaining about complexity
In the hopes it will go away
Is to create further perplexity
For others down the way.

Anti-intellectualism is a fashion statement
It makes one seem quite *au courant*
But when the rubber hits the pavement
Someone has to pay, in Reality's restaurant.

Rumsfeld said, nothin' to it,
And he shoo'd Shinseki away,
For saying he needed, to do it,
Several divisions of the infant-ray

And so men died because he lied,
Having learned his trade at Searle,
Where I know for a fact, having friends there
That this is how they made them hurl:

Seems to work and accounts for everything,
But we didn't think of it, so we're refusin'
To give you time to make it sing.
```
 0
spinoza1111 (3246)
2/18/2010 12:10:15 PM
```On Feb 18, 4:15=A0pm, Keith Thompson <ks...@mib.org> wrote:
> Richard Heathfield <r...@see.sig.invalid> writes:
> >spinoza1111wrote:
> >> On Feb 18, 12:48 am, Tim Streater <timstrea...@waitrose.com> wrote:
>
> > <prior nonsense snipped>
>
> >>> There are certainly programmers who are unable to communicate
> >>> meaningfully. I'm not one of those.
>
> >> You've given no evidence here.
>
> > It is ironic that you, who almost never support your own claims with
> > hard facts, should ask for someone else to provide evidence. It is the
> > height of hypocrisy.
> [snip]
> > <subsequent nonsense snipped>
>
> Yes,spinoza1111is wrong again, and on a topic having nothing
> to do either with C or with the supposed subject of this thread.
> Is pointing it out really a good use of time and bandwidth?

Here's the guy who solemnly approved Seebach's "off by one" attempt to
do strlen, and here, all Kiki knows is that Nilges is "wrong": Yeats
again:

We are closed in, and the key is turned
On our uncertainty; somewhere
A man is killed, or a house burned,
Yet no clear fact to be discerned:
Come build in he empty house of the stare. ...

We had fed the heart on fantasies,
The heart's grown brutal from the fare;
More substance in our enmities
Than in our love; O honey-bees,
Come build in the empty house of the stare.

>
> --
> Keith Thompson (The_Other_Keith) ks...@mib.org =A0<http://www.ghoti.net/~=
kst>
> Nokia
> "We must do something. =A0This is something. =A0Therefore, we must do thi=
s."
> =A0 =A0 -- Antony Jay and Jonathan Lynn, "Yes Minister"

```
 0
spinoza1111 (3246)
2/18/2010 12:13:31 PM
```On Feb 18, 2:40=A0pm, Richard Heathfield <r...@see.sig.invalid> wrote:
> spinoza1111wrote:
> > On Feb 18, 12:48 am, Tim Streater <timstrea...@waitrose.com> wrote:
>
> <prior nonsense snipped>
>
> >> There are certainly programmers who are unable to communicate
> >> meaningfully. I'm not one of those.
>
> > You've given no evidence here.
>
> It is ironic that you, who almost never support your own claims with
> hard facts, should ask for someone else to provide evidence. It is the
> height of hypocrisy.
>
> Nevertheless, Tim Streater is not you, and it is not unreasonable to
> expect some evidence to exist for his claims (unlike yours). I can
> provide some. (It won't convince *you*, obviously, but that doesn't
> bother me in the slightest.)
>
> I have been reading Tim Streater's articles for some time now. I have
> occasionally participated in discussions with him. In those discussions,
> I have never had any cause whatsoever to doubt his ability to
> communicate meaningfully. Anyone who wishes to assure themselves of his
> ability to communicate meaningfully need only pick a dozen samples of
> his articles at random, and read through them. (And anyone who wishes to
> discern whether his correspondent can communicate meaningfully need only
> do the same to /his/ articles.)

You're unable, as we have seen, to do a competent job at constructing
a linked list, so it stands to reason that you'll think in terms of an
external show of expertise, and make this newsgroup a popularity
contest dominated by bullies willing to lie. It's like the art dealer
told me when some thugs on the island on which I lived threatened to
disrupt my one-man show. People don't care about art anymore, just
wine, food, sex and who's in.

You don't give a flying fuck about good programming, Richard, it's
just a meal ticket for you: that's obvious. This is why you're a bully
and an enabler.
>
> <subsequent nonsense snipped>
>
> --
> Richard Heathfield <http://www.cpax.org.uk>
> Email: -http://www. +rjh@
> "Usenet is a strange place" - dmr 29 July 1999
> Sig line vacant - apply within

```
 0
spinoza1111 (3246)
2/18/2010 12:16:36 PM
```spinoza1111 wrote:
>
> You're lying.

Wrong *again*.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
```
 0
rjh (10791)
2/18/2010 12:52:12 PM
```On 18 Feb, 09:37, Richard Heathfield <r...@see.sig.invalid> wrote:
> Nick Keighley wrote:
> > On 18 Feb, 08:55, Malcolm McLean <malcolm.mcle...@btinternet.com>
> > wrote:
> >> On Feb 18, 2:53 am, Julienne Walker <happyfro...@hotmail.com> wrote:
>
> >>> I'm afraid I can't imagine how my meaning couldn't be clear: A linked
> >>> list of characters or an "array" of characters. These are one-
> >>> dimensional data structures, completely linear in concept, and easy to
> >>> visualize even for the most remedial of comp sci students. Combining
> >>> them adds complexity and relatively difficult design decisions.
> >> I'm working on DNA data at the moment. Currently I store it as
> >> conventional strings.
>
> >> However the data is a long list of ACGTs. A human can't possibly read
> >> it all, even small sections look meaningless after a bit. The eye is
> >> drawn to repeats and chance combinations like 'TAGACAT'.
> >> However genomes are not unstructured. Different areas have different
> >> statistical characteristics, though we don't know exactly what that
> >> means. My job, basically, is to take the raw strings and turn them
> >> into something else, something that humans can talk about in a
> >> sensible way.
> >> So I will need to build extra layers of structure on top of the
> >> strings.
>
> > are you agreeing or disagreeing?
>
> No, I don't think so.

though interesting, how does the stuff about DNA add to this sub-

```
 0
2/18/2010 1:34:43 PM
```On Feb 17, 9:36=A0pm, spinoza1111 <spinoza1...@yahoo.com> wrote:
> On Feb 18, 8:53=A0am, Julienne Walker <happyfro...@hotmail.com> wrote:
> > On Feb 17, 10:52=A0am,spinoza1111<spinoza1...@yahoo.com> wrote:
> > > On Feb 17, 10:07=A0pm, Julienne Walker <happyfro...@hotmail.com> wrot=
e:
> > > > On Feb 16, 7:22=A0pm,spinoza1111<spinoza1...@yahoo.com> wrote:
> > > > > On Feb 16, 9:59=A0pm, Julienne Walker <happyfro...@hotmail.com> w=
rote:
> > > > > > On Feb 16, 2:28=A0am,spinoza1111<spinoza1...@yahoo.com> wrote:
>
> > > > > > One can alleviate that waste by storing arrays of characters in=
each
> > > > > > node rather than a single character, but that increases the com=
plexity
>
> > > > > No no no no no. LINKS, please. A pointer to the segment in malloc=
ated
> > > > > space and its length.
>
> > > > A detail quite irrelevant to my point. Now you're managing a linked
> > > > list, blocks of contiguous characters, *and* the relationship betwe=
en
> > > > them to represent a single string. If the original goal is easy
> > > > modification, I'd be dubious about how successful this design is
> > > > compared to the simpler list of characters or block of characters.
>
> > > Verbiage, Julienne, of the sort that torpedoes good ideas in
> > > structured walkthroughs, because it is HARD to "modify" strings
> > > maintained as what you seem to mean by "the simpler list of character=
s
> > > or block of characters" (your meaning is not clear.
>
> > I'm afraid I can't imagine how my meaning couldn't be clear: A linked
> > list of characters or an "array" of characters. These are one-
> > dimensional data structures, completely linear in concept, and easy to
> > visualize even for the most remedial of comp sci students. Combining
> > them adds complexity and relatively difficult design decisions.
>
> No, "a linked list of string segments" solves our problem. You do wish
> to solve the problem, don't you?

I'm not aware there was a problem that needed to be solved. It seems
to me more like we've been discussing solutions looking for a problem.
Or do you have an application where both C-style strings and Paul's
better string library are woefully unsuitable? Having a concrete
problem to work with would make weighing alternatives a great deal
easier.

> > > If you mean that strings should be maintained in the current way, if =
a
> > > NUL terminated string is a "simpler" list of characters or block, the=
n
> > > making deletions and insertions is actually quite difficult and time-
> > > consuming. It requires that the entire string, no matter how long, be
> > > completely reallocated.
>
> > As for reallocation, that really depends on the current capacity and
> > your needs. Insertion wouldn't require reallocation if the blocks
> > capacity is already large enough
>
> How do you know this?

You're not the only one with experience. ;-) But it takes little more
than common sense to see that if there's room left in the glass, you
can add more water. String libraries typically allocate more memory
than needed for that very reason. It avoids excessive calls to the
memory manager.

> >. Deletion would only require
> > reallocation if you want to trim unused memory. If strings were
> > immutable, it might be a different story, but that's not the case in
> > C.
>
> > > Whereas deletions and insertions in a linked list are always simple,
> > > both conceptually (once you get the hang of it) and in terms of
> > > computational complexity. It involves no excess or wasted movement of
> > > characters.
>
> > Agreed. But let's not forget that you have more than just the link
> > surgery of a linked list. Consider the following data structure you
> > described. Each node is a pointer to a block of characters:
>
> > "this" -> "is" -> "a" -> "test"
>
> > If this string representation were to be useful at all, you'd need to
> > support deleting parts of each block (such as the "hi" from "this")
> > and inserting inside each block. I have a hard time believing how this
> > doesn't add complexity, and depending on your design decisions, it
> > could easily involve excess or wasted movement of characters.
>
> You have a hard time believing how this doesn't add complexity because
> you haven't done this type of work, can be my only conclusion here.
> This is mental complexity not "complexity".

I say it adds complexity *because* I've done this type of work. Quite
a bit of it, actually. You have a bad habit of concluding that I don't
know what I'm talking about or haven't "done my homework" when you
disagree with me.

> > > > > > of the data structure, which means you're probably going to see=
a
> > > > > > performance hit. Whether that hit is significant would require
> > > > > > profiling, but even if it weren't, I'd say the benefit of a lin=
ked
> > > > > > list is no longer clear.
>
> > > > > My entire point was that Richard's approach is wrong. In fact, a
> > > > > programmer with uni compsci would never have done what he did.
>
> > > > I went home and checked my copy of the book. Personally, I think
> > > > you're overreacting. The C Unleashed design is a viable one in that
> > > > the data structure owns its data, as opposed to having the data own=
ed
> > > > by something else and merely storing pointers to said data. In the
> > > > former case the data structure can make specific claims of correctn=
ess
> > > > and integrity while in the latter case you can end up with dangling
> > > > pointers and unexpected aliasing. On the down side, in the former c=
ase
> > > > you end up copying data around when it might not be necessary, and
> > > > making copies might not be desirable from a functionality standpoin=
t.
>
> > > This type of "ownership" is overrated.
>
>
> It is purely psychological. You're insecure with my solution because I
> am not in authority over you, whereas Richard is a bully who always
> wants to get his way, and women have a tendency to defer to bullying.
> He has a sort of "virtual" authority. But the fact remains that his
> code shows no evidence of education or skill in this matter.

Lots of words and no substance. I asked for a scientific explanation
of why that type of "ownership" is overrated, not some amateur psych
evaluation. I understand both solutions as well as the advantages and
disadvantages of both. I understand that they're suitable in different
situations, but you claim that your solution is better because
"ownership" is overrated and I want to know why.

> > > However, using Richard's solution, quite apart from its performance,
> > > if the copied data changed, you end up in many scenarios with
> > > what .Net authority and nice guy Dan Appleman calls the worst kind of
> > > error...one that you don't know about.
>
> > Scenarios such as what?
>
> Richard's code is using the copy in the linked list but the original
> data is changed.

If you maintain two copies of the same data but expect only one, the
application's design is fundamentally flawed to begin with. We're
talking about the design of the linked list itself, not stupid uses of
it.

> > > Although corporate programmers without excess university training are
> > > somewhat biased, in my experience, towards copying data, I'd say it's
> > > usually better given my compiler experience in addition to my busines=
s
> > > experience to link to it.
>
> > "Usually better" may indeed be the case in your experience. In my
> > experience, linking vs. copying is situational. Now we're entering the
> > realm of objectivity, which is a good thing. Opinions are clearly
> > stated as opinion, and words are carefully chosen so as to avoid
> > making absolute statements.
>
> Such as "oh, I think you should think like a manager and not an
> engineer?" Or "in my opinion, the fact that no insulation piece has
> been, so far, has caused any damage means it's not a problem". Or, "in
> my opinion, General Shinseki, you're asking for too many troops?" Or,
> "in my opinion, Saddam Hussein has WMDs".

emotions to guide technical arguments". You make the strangest
connections and then lay them out as if they're conclusive arguments.
Debating by confusing one's opponent only works at the lowest levels.

> > > > There are advantages and disadvantages to both, which is typical in
> > > > software design. Choose the one that best suits your needs, and you=
'll
> > > > end up with higher quality software. Being dogmatic about one or th=
e
> > > > other limits your options.
>
> > > Why is it in corporations that the most vague admonitions are used to
> > > make irrevocable and costly decisions, whereas knowledge is equated
> > > with dogma?
>
> > Failure to apply the full extent of knowledge is equated with dogma.
> > I'd find it laughable if you weren't aware of the advantages of
> > copying data and the disadvantages of linking data. But your
> > statements clearly make it appear as if copying data has no advantages
> > we were actually trying to make a decision, I'd be forcing you to
> > consider all of the alternatives I could think of so that the best
> > possible decision could be made.
>
> There is, in fact, no downside to a correctly implemented linked list
> of pointers, whereas there IS a considerable downside, which you don't
> seem to understand, to a correctly implemented link list of copied
> data. I've shown you, but shall repeat: Richard Heathfield's reusable
> tool will blow up, performance-wise, if passed large nodes

And your "better" design will blow up if linked to local data that
goes out of scope or memory that is released by unwitting client code.
I'm afraid that's a downside, despite your claim that none exist.

> creates a copy of data which has to be maintained in parallel with the
> original.

It's easy to make a library design look bad when you assume it's being
used by an idiot. The C++ container libraries take ownership of data
by copying, and nobody seems to have a problem with them. Further, by
copying pointers to the data rather than the data itself you get the

> > > > > > > Frankly, Julienne, I'm tired of the facility in which
> > > > > > > ordinary garden-variety transform "the need to think" into "w=
asting
> > > > > > > overhead" as if their brains =3D=3D their computer.
>
> > > > > > I can't decide if you're insulting me or using my post to enabl=
e
> > > > > > attacks on your usual clc nemeses. Either way I think I'll simp=
ly
> > > > > > ignore it and focus on the topic at hand.
>
> > > > > Neither. What concerns me is that in nearly all offices, a langua=
ge
> > > > > game is played that produces crumby software. Here, it's resistan=
ce to
> > > > > good solutions which are hard for some to think about based on fa=
lse
> > > > > appeals to a misapprehension of "structured programming" and the =
false
> > > > > inference from "it is difficult for me to think about this" to "t=
his
> > > > > must be an inefficient kludge".
>
> > > > May I direct you to the irony of this statement and your resistance=
to
>
> > > My dear Julienne, let us not simulate, even in dulcet tones, the
> > > corporate situation in which independence thought is reduced to a bad
> > > attitude, irrational resistance and behavior. Thank you.
>
> > Your attitude toward me has been hostile despite perfectly civil
>
> If disagreement is hostility, then who's hostile?

You're too intelligent not to realize how insulting and condescending
your posts are. Are you really trying to imply that you've managed to
insult my experience, my intelligence, my ethics, and my gender all
without knowing it? I actually find that impossible to believe. Once
again, I'm not stupid, and I'm not timid. I can see what you're doing
and I'm not afraid to point it out.
```
 0
2/18/2010 2:46:11 PM
```On Feb 18, 10:46=A0pm, Julienne Walker <happyfro...@hotmail.com> wrote:
> On Feb 17, 9:36=A0pm,spinoza1111<spinoza1...@yahoo.com> wrote:
>
>
>
>
>
> > On Feb 18, 8:53=A0am, Julienne Walker <happyfro...@hotmail.com> wrote:
> > > On Feb 17, 10:52=A0am,spinoza1111<spinoza1...@yahoo.com> wrote:
> > > > On Feb 17, 10:07=A0pm, Julienne Walker <happyfro...@hotmail.com> wr=
ote:
> > > > > On Feb 16, 7:22=A0pm,spinoza1111<spinoza1...@yahoo.com> wrote:
> > > > > > On Feb 16, 9:59=A0pm, Julienne Walker <happyfro...@hotmail.com>=
wrote:
> > > > > > > On Feb 16, 2:28=A0am,spinoza1111<spinoza1...@yahoo.com> wrote=
:
>
> > > > > > > One can alleviate that waste by storing arrays of characters =
in each
> > > > > > > node rather than a single character, but that increases the c=
omplexity
>
> > > > > > No no no no no. LINKS, please. A pointer to the segment in mall=
ocated
> > > > > > space and its length.
>
> > > > > A detail quite irrelevant to my point. Now you're managing a link=
ed
> > > > > list, blocks of contiguous characters, *and* the relationship bet=
ween
> > > > > them to represent a single string. If the original goal is easy
> > > > > modification, I'd be dubious about how successful this design is
> > > > > compared to the simpler list of characters or block of characters=
..
>
> > > > Verbiage, Julienne, of the sort that torpedoes good ideas in
> > > > structured walkthroughs, because it is HARD to "modify" strings
> > > > maintained as what you seem to mean by "the simpler list of charact=
ers
> > > > or block of characters" (your meaning is not clear.
>
> > > I'm afraid I can't imagine how my meaning couldn't be clear: A linked
> > > list of characters or an "array" of characters. These are one-
> > > dimensional data structures, completely linear in concept, and easy t=
o
> > > visualize even for the most remedial of comp sci students. Combining
> > > them adds complexity and relatively difficult design decisions.
>
> > No, "a linked list of string segments" solves our problem. You do wish
> > to solve the problem, don't you?
>
> I'm not aware there was a problem that needed to be solved. It seems

No, Richard Heathfield's code was intended to "solve the problem of a
reusable tool for managing a linked list", but it doesn't, because it
needlessly copies characters and duplicates data. A simpler (both
conceptually and in terms of computational complexity) solution is to
use a strongly typed pointer and preprocessor macros, or void
pointers.

> to me more like we've been discussing solutions looking for a problem.
> Or do you have an application where both C-style strings and Paul's
> better string library are woefully unsuitable? Having a concrete
> problem to work with would make weighing alternatives a great deal
> easier.

That is separate. Yes, we want to get rid of string.h.

>
> > > > If you mean that strings should be maintained in the current way, i=
f a
> > > > NUL terminated string is a "simpler" list of characters or block, t=
hen
> > > > making deletions and insertions is actually quite difficult and tim=
e-
> > > > consuming. It requires that the entire string, no matter how long, =
be
> > > > completely reallocated.
>
> > > As for reallocation, that really depends on the current capacity and
> > > your needs. Insertion wouldn't require reallocation if the blocks
> > > capacity is already large enough
>
> > How do you know this?
>
> You're not the only one with experience. ;-) But it takes little more
> than common sense to see that if there's room left in the glass, you
> can add more water. String libraries typically allocate more memory
> than needed for that very reason. It avoids excessive calls to the
> memory manager.

That makes little sense. You pork out on memory to avoid excessive
calls when a better design would use minimal memory.
>
>
>
>
>
> > >. Deletion would only require
> > > reallocation if you want to trim unused memory. If strings were
> > > immutable, it might be a different story, but that's not the case in
> > > C.
>
> > > > Whereas deletions and insertions in a linked list are always simple=
,
> > > > both conceptually (once you get the hang of it) and in terms of
> > > > computational complexity. It involves no excess or wasted movement =
of
> > > > characters.
>
> > > Agreed. But let's not forget that you have more than just the link
> > > surgery of a linked list. Consider the following data structure you
> > > described. Each node is a pointer to a block of characters:
>
> > > "this" -> "is" -> "a" -> "test"
>
> > > If this string representation were to be useful at all, you'd need to
> > > support deleting parts of each block (such as the "hi" from "this")
> > > and inserting inside each block. I have a hard time believing how thi=
s
> > > doesn't add complexity, and depending on your design decisions, it
> > > could easily involve excess or wasted movement of characters.
>
> > You have a hard time believing how this doesn't add complexity because
> > you haven't done this type of work, can be my only conclusion here.
> > This is mental complexity not "complexity".
>
> I say it adds complexity *because* I've done this type of work. Quite
> a bit of it, actually. You have a bad habit of concluding that I don't
> know what I'm talking about or haven't "done my homework" when you
> disagree with me.

I think corporate life causes programmers to deskill themselves. As
the sociologist Adorno pointed out in a chapter in his 1948 book,
people's flaw first appear "in the organs whose services they sell"
while on an individual basis they remain as individuals charming and
intelligent people. But on the job, vending flawed products, we are
corrupted using a form of even-handedness that refuses to confront the
products in the "organs".
>
>
>
>
>
> > > > > > > of the data structure, which means you're probably going to s=
ee a
> > > > > > > performance hit. Whether that hit is significant would requir=
e
> > > > > > > profiling, but even if it weren't, I'd say the benefit of a l=
inked
> > > > > > > list is no longer clear.
>
> > > > > > My entire point was that Richard's approach is wrong. In fact, =
a
> > > > > > programmer with uni compsci would never have done what he did.
>
> > > > > I went home and checked my copy of the book. Personally, I think
> > > > > you're overreacting. The C Unleashed design is a viable one in th=
at
> > > > > the data structure owns its data, as opposed to having the data o=
wned
> > > > > by something else and merely storing pointers to said data. In th=
e
> > > > > former case the data structure can make specific claims of correc=
tness
> > > > > and integrity while in the latter case you can end up with dangli=
ng
> > > > > pointers and unexpected aliasing. On the down side, in the former=
case
> > > > > you end up copying data around when it might not be necessary, an=
d
> > > > > making copies might not be desirable from a functionality standpo=
int.
>
> > > > This type of "ownership" is overrated.
>
>
> > It is purely psychological. You're insecure with my solution because I
> > am not in authority over you, whereas Richard is a bully who always
> > wants to get his way, and women have a tendency to defer to bullying.
> > He has a sort of "virtual" authority. But the fact remains that his
> > code shows no evidence of education or skill in this matter.
>
> Lots of words and no substance. I asked for a scientific explanation
> of why that type of "ownership" is overrated, not some amateur psych
> evaluation. I understand both solutions as well as the advantages and
> disadvantages of both. I understand that they're suitable in different
> situations, but you claim that your solution is better because
> "ownership" is overrated and I want to know why.

Because there's absolutely no reason whatsoever to copy data. NEVER,
given the problem statement. If you have a pointer to the data and
there is no concurrent thread that is changing the source, then the
linked list that is based on a pointer will be just as "stable" as a
copy. The programmer, like Heathfield, who makes a copy is wasting
computer time, since IF the data is being altered concurrently, it may
change DURING THE COPY, which would make the copy invalid.

This isn't dogma. Dogma in these threads are statements that deny the
ability to know based on misbegotten standards. The problem in
corporate life is the imposed, monastic, *omerta* and humility that is
imposed on low-level knowers, something ultimately corrupting, and the
effects of which are evident in posters here.

>
> > > > However, using Richard's solution, quite apart from its performance=
,
> > > > if the copied data changed, you end up in many scenarios with
> > > > what .Net authority and nice guy Dan Appleman calls the worst kind =
of
> > > > error...one that you don't know about.
>
> > > Scenarios such as what?
>
> > Richard's code is using the copy in the linked list but the original
> > data is changed.
>
> If you maintain two copies of the same data but expect only one, the
> application's design is fundamentally flawed to begin with. We're
> talking about the design of the linked list itself, not stupid uses of
> it.

Which means that the copy is risky in any situation where the source
may change.

>
>
>
>
>
> > > > Although corporate programmers without excess university training a=
re
> > > > somewhat biased, in my experience, towards copying data, I'd say it=
's
> > > > usually better given my compiler experience in addition to my busin=
ess
> > > > experience to link to it.
>
> > > "Usually better" may indeed be the case in your experience. In my
> > > experience, linking vs. copying is situational. Now we're entering th=
e
> > > realm of objectivity, which is a good thing. Opinions are clearly
> > > stated as opinion, and words are carefully chosen so as to avoid
> > > making absolute statements.
>
> > Such as "oh, I think you should think like a manager and not an
> > engineer?" Or "in my opinion, the fact that no insulation piece has
> > been, so far, has caused any damage means it's not a problem". Or, "in
> > my opinion, General Shinseki, you're asking for too many troops?" Or,
> > "in my opinion, Saddam Hussein has WMDs".
>
> emotions to guide technical arguments". You make the strangest
> connections and then lay them out as if they're conclusive arguments.
> Debating by confusing one's opponent only works at the lowest levels.

I'm sorry you're confused, but you seem to have missed the class on
linked lists. It seems to me that you're being the emotional one,
where the "emotion" is the reluctance to make a decision based on the
facts, a kind of anomie not thought of, in the corporate world, as an
emotion, but which is one nonetheless.

The willed absence of emotion can itself said to be an emotion (its
name is anhedonia in some contexts, anomie in others) insofar as it
blocks action based on reason.

Furthermore, it is ironic that as a woman you should try a traditional
argument, used against women: that they are thinking "emotionally". In
my experience, too many corporate women use strikingly traditional
memes when talking to men, and the result is that men are scared to be
"emotional", when in my view, good emotion creates energy and
creativity.

>
>
>
>
>
> > > > > There are advantages and disadvantages to both, which is typical =
in
> > > > > software design. Choose the one that best suits your needs, and y=
ou'll
> > > > > end up with higher quality software. Being dogmatic about one or =
the
> > > > > other limits your options.
>
> > > > Why is it in corporations that the most vague admonitions are used =
to
> > > > make irrevocable and costly decisions, whereas knowledge is equated
> > > > with dogma?
>
> > > Failure to apply the full extent of knowledge is equated with dogma.
> > > I'd find it laughable if you weren't aware of the advantages of
> > > copying data and the disadvantages of linking data. But your
> > > statements clearly make it appear as if copying data has no advantage=
s
> > > we were actually trying to make a decision, I'd be forcing you to
> > > consider all of the alternatives I could think of so that the best
> > > possible decision could be made.
>
> > There is, in fact, no downside to a correctly implemented linked list
> > of pointers, whereas there IS a considerable downside, which you don't
> > seem to understand, to a correctly implemented link list of copied
> > data. I've shown you, but shall repeat: Richard Heathfield's reusable
> > tool will blow up, performance-wise, if passed large nodes
>
> And your "better" design will blow up if linked to local data that
> goes out of scope or memory that is released by unwitting client code.
> I'm afraid that's a downside, despite your claim that none exist.

This is in fact equivalent to the risks of copying data.

If the source of the copied data is released, this may mean that it's
no longer valid. The copy will still exist with no error indication in
this scenario, and the program will not fail...instead "the worst kind
of bug" will result: the one nobody knows about.

This is in fact a greater risk, and added to the slower performance of
the copying solution, it means that the copying solution is almost
never acceptable, except as a documented nondefault alternative to a
option.

>
> > creates a copy of data which has to be maintained in parallel with the
> > original.
>
> It's easy to make a library design look bad when you assume it's being
> used by an idiot. The C++ container libraries take ownership of data
> by copying, and nobody seems to have a problem with them. Further, by
> copying pointers to the data rather than the data itself you get the
>
>
>
>
>
> > > > > > > > Frankly, Julienne, I'm tired of the facility in which
> > > > > > > > ordinary garden-variety transform "the need to think" into =
"wasting
> > > > > > > > overhead" as if their brains =3D=3D their computer.
>
> > > > > > > I can't decide if you're insulting me or using my post to ena=
ble
> > > > > > > attacks on your usual clc nemeses. Either way I think I'll si=
mply
> > > > > > > ignore it and focus on the topic at hand.
>
> > > > > > Neither. What concerns me is that in nearly all offices, a lang=
uage
> > > > > > game is played that produces crumby software. Here, it's resist=
ance to
> > > > > > good solutions which are hard for some to think about based on =
false
> > > > > > appeals to a misapprehension of "structured programming" and th=
e false
> > > > > > inference from "it is difficult for me to think about this" to =
"this
> > > > > > must be an inefficient kludge".
>
> > > > > May I direct you to the irony of this statement and your resistan=
ce to
>
> > > > My dear Julienne, let us not simulate, even in dulcet tones, the
> > > > corporate situation in which independence thought is reduced to a b=
> > > > attitude, irrational resistance and behavior. Thank you.
>
> > > Your attitude toward me has been hostile despite perfectly civil
>
> > If disagreement is hostility, then who's hostile?
>
> You're too intelligent not to realize how insulting and condescending
> your posts are. Are you really trying to imply that you've managed to
> insult my experience, my intelligence, my ethics, and my gender all
> without knowing it? I actually find that impossible to believe. Once
> again, I'm not stupid, and I'm not timid. I can see what you're doing
> and I'm not afraid to point it out.

Part of the problem is that male bullying behavior replaces
traditional male (and female: human) arguments based on reason and
facts to such an extent that the latter is classed with bullying. But
I don't accept, not in the slightest, being classed with thugs.

I'm saying you're wrong, and I am explaining it as part of corporate
corruption with which I am familiar: the false even-handedness which
ignores incompetence and bullying.

This is NOTHING like the lies and bullying to which I'm being
subjected to in this newsgroup. In each response to you, I've
addressed the issues, whereas Heathfield and Seebach, as we "speak"
are repeating the canard "Nilges is incompetent and makes errors"
without in any of those posts providing even a precis or summary of
the reasons, for they cannot present any, whereas I have clear
evidence of their incompetence: neither was able to even make a start
on the replace() challenge, Heathfield wrote a "linked list tool"
without pointing to data, Seebach presented a "strlen" with a serious
error, etc.

And don't presume even to say that I've "insulted" your gender. That
is an utter falsehood. I have not patronized nor talked down to you in
the slightest. I am instead arguing for a position: that only an
incompetent would have presented a linked list that copies
unpredictable data into the nodes. This has nothing to do with gender.

```
 0
spinoza1111 (3246)
2/18/2010 3:51:27 PM
```On Feb 18, 9:34=A0pm, Nick Keighley <nick_keighley_nos...@hotmail.com>
wrote:
> On 18 Feb, 09:37, Richard Heathfield <r...@see.sig.invalid> wrote:
>
>
>
>
>
> > Nick Keighley wrote:
> > > On 18 Feb, 08:55, Malcolm McLean <malcolm.mcle...@btinternet.com>
> > > wrote:
> > >> On Feb 18, 2:53 am, Julienne Walker <happyfro...@hotmail.com> wrote:
>
> > >>> I'm afraid I can't imagine how my meaning couldn't be clear: A link=
ed
> > >>> list of characters or an "array" of characters. These are one-
> > >>> dimensional data structures, completely linear in concept, and easy=
to
> > >>> visualize even for the most remedial of comp sci students. Combinin=
g
> > >>> them adds complexity and relatively difficult design decisions.
> > >> I'm working on DNA data at the moment. Currently I store it as
> > >> conventional strings.
>
> > >> However the data is a long list of ACGTs. A human can't possibly rea=
d
> > >> it all, even small sections look meaningless after a bit. The eye is
> > >> drawn to repeats and chance combinations like 'TAGACAT'.
> > >> However genomes are not unstructured. Different areas have different
> > >> statistical characteristics, though we don't know exactly what that
> > >> means. My job, basically, is to take the raw strings and turn them
> > >> into something else, something that humans can talk about in a
> > >> sensible way.
> > >> So I will need to build extra layers of structure on top of the
> > >> strings.
>
> > > are you agreeing or disagreeing?
>
> > No, I don't think so.
>
> though interesting, how does the stuff about DNA add to this sub-

Malcolm is describing a real application that needs data structures
above the level of characters and strings. In fact, it sounds ideal
```
 0
spinoza1111 (3246)
2/18/2010 3:52:56 PM
```On Feb 18, 10:51=A0am, spinoza1111 <spinoza1...@yahoo.com> wrote:
>
> <snip>

We'll have to agree to disagree then. Your technical points are valid
in context, but your personality poisons any chance of having a good
debate with you. Any technical discussion inevitably devolves into
veiled insults, condescension, attacks on "corporate behavior",
Heathfield, and poetry when you have nothing useful left to say (in my
opinion).

Honestly, I'm tired of talking to a brick wall. Let me know when
you're ready to take me seriously and we may actually be able to chat
in a civil manner.

> And don't presume even to say that I've "insulted" your gender. That
> is an utter falsehood. I have not patronized nor talked down to you in
> the slightest. I am instead arguing for a position: that only an
> incompetent would have presented a linked list that copies
> unpredictable data into the nodes. This has nothing to do with gender.

You're in no position to tell me not to defend myself when I feel I'm
being "bullied" by a "thug", since you're so adamant about taking that
right for yourself at every turn.
```
 0
2/18/2010 4:23:59 PM
```Richard Heathfield <rjh@see.sig.invalid> writes:
> Keith Thompson wrote:
[...]
>> Yes, spinoza1111 is wrong again, and on a topic having nothing
>> to do either with C or with the supposed subject of this thread.
>> Is pointing it out really a good use of time and bandwidth?
>
> Put it this way - although I haven't measured it, I would estimate
> that the number of his errors that I actually address is significantly
> under 1% of the total errors he posts. (If I were to attempt to
> address every error he makes, (a) I wouldn't ever get any real work
> done, and (b) I'd be plonked by most of this group's subscribers.)
>
> So it could be a lot worse. On the other hand, I acknowledge that it
> could be better.

Consider this.  I read nearly none of spinoza1111's articles, and
nearly all of yours.  I don't see you addressing 1% of his errors;
I see you spending a much larger percentage of your time addressing
his errors.  I'm sure I'm not the only one.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
```
 0
kst-u (21963)
2/18/2010 4:44:38 PM
```spinoza1111 wrote:

<snip lots of same ol' same ol'>

>  I have clear
> evidence of their incompetence: neither was able to even make a start
> on the replace() challenge,

Declining to enter your "challenge" shows not incompetence but good
judgement.

> Heathfield wrote a "linked list tool"
> without pointing to data,

Rubbish. In the code you're talking about, every single link in the list
points to data. Bozo.

> Seebach presented a "strlen" with a serious
> error, etc.

He had an off-by-one error which he acknowledged the moment it was
reported. You, on the other hand, have to have your errors explained to
you in noxious detail before you manage to get your head around them.
Then it takes you a few more days, in some cases, to correct them. And,
if we're patient enough, we'll find you making the *same* errors a few
months or years down the road, and having to have them explained to you
*again*.

> And don't presume even to say that I've "insulted" your gender. That
> is an utter falsehood.

Rubbish. You're a sexist and everybody knows it; I cannot recall ever
seeing a reply from you to a woman that wasn't outrageously
condescending in tone. That would be bad enough even if you had

> I have not patronized nor talked down to you in
> the slightest. I am instead arguing for a position: that only an
> incompetent would have presented a linked list that copies
> unpredictable data into the nodes. This has nothing to do with gender.

I agree it's nothing to do with gender. Julienne Walker has presented
sound arguments in defence of data containment which you have completely
failed to address, preferring to revel in sexist claptrap and amateur
psychobabble. If you have any serious answer to her arguments, post them.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
```
 0
rjh (10791)
2/18/2010 4:48:35 PM
```Keith Thompson wrote:
>
> Consider this.  I read nearly none of spinoza1111's articles, and
> nearly all of yours.  I don't see you addressing 1% of his errors;
> I see you spending a much larger percentage of your time addressing
> his errors.  I'm sure I'm not the only one.

Well, I was just trying to put a little shine on the problem. Never mind.

It might be interesting to take what we might call the "OLE" debate out
of the current stupid context and move it into a fresh thread.

In fact, I'll do just that. It has to be at least a year or so since I

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
```
 0
rjh (10791)
2/18/2010 4:52:40 PM
```On 2010-02-18, Julienne Walker <happyfrosty@hotmail.com> wrote:
> Agreed. But let's not forget that you have more than just the link
> surgery of a linked list. Consider the following data structure you
> described. Each node is a pointer to a block of characters:
>
> "this" -> "is" -> "a" -> "test"
>
> If this string representation were to be useful at all, you'd need to
> support deleting parts of each block (such as the "hi" from "this")
> and inserting inside each block. I have a hard time believing how this
> could easily involve excess or wasted movement of characters.

It could.  However:

* Compared to a linked list of single characters, it has much lower
* Compared to a single giant array, it requires much less copying and
moving to resize, insert, or delete

So there are cases where something like this is worth it.  If you're
doing a ton of string inserts of unpredictable lengths, it's probably
worth it.

-s
--
Copyright 2010, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
```
 0
usenet-nospam (2309)
2/18/2010 5:47:18 PM
```On Feb 18, 12:47=A0pm, Seebs <usenet-nos...@seebs.net> wrote:
> On 2010-02-18, Julienne Walker <happyfro...@hotmail.com> wrote:
>
> > Agreed. But let's not forget that you have more than just the link
> > surgery of a linked list. Consider the following data structure you
> > described. Each node is a pointer to a block of characters:
>
> > "this" -> "is" -> "a" -> "test"
>
> > If this string representation were to be useful at all, you'd need to
> > support deleting parts of each block (such as the "hi" from "this")
> > and inserting inside each block. I have a hard time believing how this
> > doesn't add complexity, and depending on your design decisions, it
> > could easily involve excess or wasted movement of characters.
>
> It could. =A0However:
>
> * Compared to a linked list of single characters, it has much lower
> * Compared to a single giant array, it requires much less copying and
> =A0 moving to resize, insert, or delete
>
> So there are cases where something like this is worth it.

Absolutely. I wouldn't suggest that it's not a good design. My problem
is with spinoza1111 pushing it as the "best" solution, regardless of
context.
```
 0
2/18/2010 7:19:05 PM
```On Feb 18, 7:47=A0pm, Seebs <usenet-nos...@seebs.net> wrote:
> On 2010-02-18, Julienne Walker <happyfro...@hotmail.com> wrote:
>
> > Agreed. But let's not forget that you have more than just the link
> > surgery of a linked list. Consider the following data structure you
> > described. Each node is a pointer to a block of characters:
>
> > "this" -> "is" -> "a" -> "test"
>
> > If this string representation were to be useful at all, you'd need to
> > support deleting parts of each block (such as the "hi" from "this")
> > and inserting inside each block. I have a hard time believing how this
> > doesn't add complexity, and depending on your design decisions, it
> > could easily involve excess or wasted movement of characters.
>
> It could. =A0However:
>
> * Compared to a linked list of single characters, it has much lower
> * Compared to a single giant array, it requires much less copying and
> =A0 moving to resize, insert, or delete
>
> So there are cases where something like this is worth it. =A0If you're
> doing a ton of string inserts of unpredictable lengths, it's probably
> worth it.
>
I used exactly that strucutre for a text editor I wrote. This was back
in the days when a more experienced programmer told me "you won't get
a full screen editor using just the routines in conio.h".
The text was a linked list of line, rather than words. So wht that
meant was that the user could scroll to the middle of the text, and
start typing. The line at the insertion point expanded, the characters
being moved along O(N) in line length. When the characters fell off
the end of the screen it became a soft newline, and new link was
inserted O(1). Deletes were of course fiddly, because you had to merge
the soft newlines, in fact deleting a character could be O(N) in text
legnth, and the thing slowed down very noticeably.
(He was right about conio.h. I had to write little assembly routines
to poke the screen memory directly).
```
 0
2/18/2010 7:25:48 PM
```Malcolm McLean <malcolm.mclean5@btinternet.com> writes:

> On Feb 18, 7:47 pm, Seebs <usenet-nos...@seebs.net> wrote:
>> On 2010-02-18, Julienne Walker <happyfro...@hotmail.com> wrote:
>>
>> > Agreed. But let's not forget that you have more than just the link
>> > surgery of a linked list. Consider the following data structure you
>> > described. Each node is a pointer to a block of characters:
>>
>> > "this" -> "is" -> "a" -> "test"
>>
>> > If this string representation were to be useful at all, you'd need to
>> > support deleting parts of each block (such as the "hi" from "this")
>> > and inserting inside each block. I have a hard time believing how this
>> > doesn't add complexity, and depending on your design decisions, it
>> > could easily involve excess or wasted movement of characters.
>>
>> It could.  However:
>>
>> * Compared to a linked list of single characters, it has much lower
>> * Compared to a single giant array, it requires much less copying and
>>   moving to resize, insert, or delete
>>
>> So there are cases where something like this is worth it.  If you're
>> doing a ton of string inserts of unpredictable lengths, it's probably
>> worth it.
>>
> I used exactly that strucutre for a text editor I wrote. This was back
> in the days when a more experienced programmer told me "you won't get
> a full screen editor using just the routines in conio.h".
> The text was a linked list of line, rather than words. So wht that
> meant was that the user could scroll to the middle of the text, and
> start typing. The line at the insertion point expanded, the characters
> being moved along O(N) in line length. When the characters fell off
> the end of the screen it became a soft newline, and new link was
> inserted O(1). Deletes were of course fiddly, because you had to merge
> the soft newlines, in fact deleting a character could be O(N) in text
> legnth, and the thing slowed down very noticeably.
> (He was right about conio.h. I had to write little assembly routines
> to poke the screen memory directly).

Why didnt you just do it in C?

```
 0
rgrdev_ (1097)
2/18/2010 7:41:02 PM
```[representing a string with a linked list of ministrings]

Malcolm McLean wrote:

<snip>

> I used exactly that strucutre for a text editor I wrote. This was back
> in the days when a more experienced programmer told me "you won't get
> a full screen editor using just the routines in conio.h".

He was right. You need other stuff, too - e.g. string.h, stdlib.h,
stdio.h...

> The text was a linked list of line, rather than words. So wht that
> meant was that the user could scroll to the middle of the text, and
> start typing. The line at the insertion point expanded, the characters
> being moved along O(N) in line length.

Better: let each line be represented by two strings, with the split
being at the insertion point. To insert characters, you simply append to
the left string. Backspace is easy too, obviously. If you keep a pointer
into the second string, delete becomes reasonably easy too. When the
user moves the cursor, it's just a matter of moving stuff over from one
string to the other.

> When the characters fell off
> the end of the screen it became a soft newline, and new link was
> inserted O(1). Deletes were of course fiddly, because you had to merge
> the soft newlines, in fact deleting a character could be O(N) in text
> legnth, and the thing slowed down very noticeably.
> (He was right about conio.h. I had to write little assembly routines
> to poke the screen memory directly).

No, you didn't have to do that. Assuming 80x25 under MS-DOS (fair
assumption?):

void scrwrite(const char *s, int x, int y)
{
char *p = (char *)0xb8000000UL; /* use large memory model */
p += y * 160; /* add range checking for y */
p += x * 2; /* add range checking for x. The 2 is because
video RAM was in byte pairs, for character
and attribute */
while(*p++ = *s++) p++;
}

That's the basic idea, anyway, but obviously you'd want something a
little more sophisticated than that. For example, you might want to
handle the attribute bytes too (colour, blink, etc). And/or you might
want to be able to deal intelligently with word wrap, etc.

By the way, b8000000 was the base address of video RAM for colour VGA
monitors. For monochrome, you would have used b0000000 instead. If you
needed to detect the monochrome/colour status at runtime, that was
possible using an int86() call. No assembly language required.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
```
 0
rjh (10791)
2/18/2010 9:08:20 PM
```On 2010-02-18, Julienne Walker <happyfrosty@hotmail.com> wrote:
> Absolutely. I wouldn't suggest that it's not a good design. My problem
> is with spinoza1111 pushing it as the "best" solution, regardless of
> context.

Ahh, yeah.

Well, I guess, I don't get the impression that he's the sort of person
who deals well with the notion that there is more than one good way
to go about something, but that different approaches would be suited to
different environments.

-s
--
Copyright 2010, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
```
 0
usenet-nospam (2309)
2/18/2010 9:15:31 PM
```On Thu, 18 Feb 2010 21:08:20 +0000, Richard Heathfield wrote:

> [representing a string with a linked list of ministrings]
>
> Malcolm McLean wrote:
>
>
>> the soft newlines, in fact deleting a character could be O(N) in text
>> legnth, and the thing slowed down very noticeably. (He was right about
>> conio.h. I had to write little assembly routines to poke the screen
>> memory directly).
>
> No, you didn't have to do that. Assuming 80x25 under MS-DOS (fair
> assumption?):
>
> void scrwrite(const char *s, int x, int y) {
>    char *p = (char *)0xb8000000UL; /* use large memory model */ p += y *
>    160; /* add range checking for y */ p += x * 2; /* add range checking
>    for x. The 2 is because
>                   video RAM was in byte pairs, for character and
>                   attribute */
>    while(*p++ = *s++) p++;
> }
>
> That's the basic idea, anyway, but obviously you'd want something a
> little more sophisticated than that. For example, you might want to
> handle the attribute bytes too (colour, blink, etc). And/or you might
> want to be able to deal intelligently with word wrap, etc.
>
> By the way, b8000000 was the base address of video RAM for colour VGA
> monitors. For monochrome, you would have used b0000000 instead. If you
> needed to detect the monochrome/colour status at runtime, that was
> possible using an int86() call. No assembly language required.

FYI:
The reason you had to use assembler was because writing to video-ram interfered
with the video ram being accessed simultaniously by the video card.
You had to wait for the vertical retrace to write to the RAM without visual
glitches.

HTH,
AvK

```
 0
root32 (398)
2/18/2010 11:36:30 PM
```Moi wrote:
<snip>

>
> FYI:
> The reason you had to use assembler was because writing to video-ram interfered
> with the video ram being accessed simultaniously by the video card.
> You had to wait for the vertical retrace to write to the RAM without visual
> glitches.

You could do that in C, too, using the inportb() extension:

void vsync(void)
{
while(inportb(0x3da) & 8)
{
continue;
}
while(!(inportb(0x3da) & 8))
{
continue;
}
}

(Of course, if you try this on a Cray or a mobile phone, you're likely
to be disappointed.)

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
```
 0
rjh (10791)
2/19/2010 12:18:48 AM
```On Fri, 19 Feb 2010 00:18:48 +0000, Richard Heathfield wrote:

> Moi wrote:
> <snip>
>
>
>> FYI:
>> The reason you had to use assembler was because writing to video-ram
>> interfered with the video ram being accessed simultaniously by the
>> video card. You had to wait for the vertical retrace to write to the
>> RAM without visual glitches.
>
> You could do that in C, too, using the inportb() extension:
>
> void vsync(void)
> {
>    while(inportb(0x3da) & 8)
>    {
>      continue;
>    }
>    while(!(inportb(0x3da) & 8))
>    {
>      continue;
>    }
> }
>
> (Of course, if you try this on a Cray or a mobile phone, you're likely
> to be disappointed.)

People with Crays have other things to get excited about.

Yes, you're right of course.
IIRC, the other trick was switching the pages.  Hercules had four, except
in graphics mode (which meant: bitmapped with a strange addressing scheme;
bypassing the character generator-ROM)

AvK
```
 0
root32 (398)
2/19/2010 12:28:26 AM
```On Feb 19, 5:15=A0am, Seebs <usenet-nos...@seebs.net> wrote:
> On 2010-02-18, Julienne Walker <happyfro...@hotmail.com> wrote:
>
> > Absolutely. I wouldn't suggest that it's not a good design. My problem
> > is withspinoza1111pushing it as the "best" solution, regardless of
> > context.
>
> Ahh, yeah.
>
> Well, I guess, I don't get the impression that he's the sort of person
> who deals well with the notion that there is more than one good way
> to go about something, but that different approaches would be suited to
> different environments.

There was only one question as regards Heathfield's "C Unleashed"
linked list. The problem was "developing a reusable tool for a linked
list of any sort of data". His solution was to copy the value of each
element, which takes O(N) time where N is the number of bytes in the
element.

A better solution (which takes constant time for each element and
which doesn't "break" if presented with unusually long elements) would
have been to use pointers to void in each node to point to the
elements.

An even better solution would be to use the preprocessor in a
disciplined way to make sure the pointer is strongly typed as in this
extempore, untested, uncompiled example:

#define NODE(datatype, structName)
structName node { datatype * nodeValuePtr; node * nextPtr; };
{ \
if ((newNodePtr =3D malloc(sizeof(node)) =3D=3D 0) abort();
(*newNodePtr)->nodeValuePtr =3D &newNodeValue; \
(*newNodePtr)->nextPtr =3D 0; \
(*lastNodePtr)->newNodePtr; \
}

Note that the ADDNODE runs in constant time, whereas Richard's plan
runs O(N).

Weasel words ("different environments") aren't an argument. The
"environment" is strictly defined: it is one in which the programmer
needs or wants a reusable tool for linked lists.

>
> -s
> --
> Copyright 2010, all wrongs reversed. =A0Peter Seebach / usenet-nos...@see=
bs.nethttp://www.seebs.net/log/<-- lawsuits, religion, and funny picturesht=
tp://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!

```
 0
spinoza1111 (3246)
2/19/2010 6:55:02 AM
```On Feb 19, 12:52=A0am, Richard Heathfield <r...@see.sig.invalid> wrote:
> Keith Thompson wrote:
>
> > Consider this. =A0I read nearly none ofspinoza1111'sarticles, and
> > nearly all of yours. =A0I don't see you addressing 1% of his errors;

(Cue Twilight Zone theme) Come with us now to another dimension, that
of Kiki, who's killed spinoza but knows all the same how many errors
he makes (Twilight Zone theme reaches its climax)

> > I see you spending a much larger percentage of your time addressing
> > his errors. =A0I'm sure I'm not the only one.
>
> Well, I was just trying to put a little shine on the problem. Never mind.
>
> It might be interesting to take what we might call the "OLE" debate out
> of the current stupid context and move it into a fresh thread.
>
> In fact, I'll do just that. It has to be at least a year or so since I
>
> --
> Richard Heathfield <http://www.cpax.org.uk>
> Email: -http://www. +rjh@
> "Usenet is a strange place" - dmr 29 July 1999
> Sig line vacant - apply within

```
 0
spinoza1111 (3246)
2/19/2010 6:57:58 AM
```On Feb 19, 12:48=A0am, Richard Heathfield <r...@see.sig.invalid> wrote:
> spinoza1111wrote:
>
> <snip lots of same ol' same ol'>
>
> > =A0I have clear
> > evidence of their incompetence: neither was able to even make a start
> > on the replace() challenge,
>
> Declining to enter your "challenge" shows not incompetence but good
> judgement.

Why? But I agree. It doesn't show incompetence. Try cowardice.
>
> > Heathfield wrote a "linked list tool"
> > without pointing to data,
>
> Rubbish. In the code you're talking about, every single link in the list
> points to data. Bozo.

Richard (a Christian Fundamentalist) uses literal reading
strategically, in the manner of Fundamentalists. That is, Christian
Fundamentalism, by insisting that the Bible is literally true, enables
"pastors" (older men) to make, in fact, any ridiculous interpretation
they like. For example, some say that Cain and Abel mated with
subhumans (Neanderthals in some "scientific creationism" accounts) in
order to give Adam and Eve grandchildren without doing the nasty with
their sisters.

Here, he uses the fact that to be a linked list at all, every node
must point to the next node. Fortunately, he's not so stupid as to
present an array as a linked list although as our Pastor he might pull
such a stunt rather than let us think.

But, of course, my point was that the DATA in the list is the DATA and
not a link, and nobody with a halfway decent education in data
structures would have proposed such a stupid design, save, perhaps,
for a linked list of data elements whose type is simple and fixed in
length...not a "reusable tool".

>
> =A0> Seebach presented a "strlen" with a serious
>
> > error, etc.
>
> He had an off-by-one error which he acknowledged the moment it was
> reported. You, on the other hand, have to have your errors explained to

That's because my errors (testing an invariant in a for, etc.), are
matters of interpretation and style and not massive boners.

> you in noxious detail before you manage to get your head around them.
> Then it takes you a few more days, in some cases, to correct them. And,
> if we're patient enough, we'll find you making the *same* errors a few
> months or years down the road, and having to have them explained to you
> *again*.

You're talking here, probably, about the fact that I unnecessarily
included malloc.h and capitalized H. These were trivial errors, and
you showed us that you were completely incompetent to read code, since
we know that it would have established your sagging chops to find an
important bug.  As it happened, there were five real bugs, and I fixed
them all in a few hours, no thanks to any of your efforts.

>
> > And don't presume even to say that I've "insulted" your gender. That
> > is an utter falsehood.
>
> Rubbish. You're a sexist and everybody knows it; I cannot recall ever
> seeing a reply from you to a woman that wasn't outrageously
> condescending in tone. That would be bad enough even if you had
> something to be condescending about.

When all else fails, Sir Richard Heathalot mounts his nag and defends

>
> =A0> I have not patronized nor talked down to you in
>
> > the slightest. I am instead arguing for a position: that only an
> > incompetent would have presented a linked list that copies
> > unpredictable data into the nodes. This has nothing to do with gender.
>
> I agree it's nothing to do with gender. Julienne Walker has presented
> sound arguments in defence of data containment which you have completely
> failed to address, preferring to revel in sexist claptrap and amateur
> psychobabble. If you have any serious answer to her arguments, post them.
>
> --
> Richard Heathfield <http://www.cpax.org.uk>
> Email: -http://www. +rjh@
> "Usenet is a strange place" - dmr 29 July 1999
> Sig line vacant - apply within

```
 0
spinoza1111 (3246)
2/19/2010 7:08:12 AM
```On Feb 19, 12:23=A0am, Julienne Walker <happyfro...@hotmail.com> wrote:
> On Feb 18, 10:51=A0am,spinoza1111<spinoza1...@yahoo.com> wrote:
>
>
>
> > <snip>
>
> We'll have to agree to disagree then. Your technical points are valid
> in context, but your personality poisons any chance of having a good
> debate with you. Any technical discussion inevitably devolves into
> veiled insults, condescension, attacks on "corporate behavior",
> Heathfield, and poetry when you have nothing useful left to say (in my
> opinion).

Good poetry, too. I taught myself how since I teach creative writing,
from the Norton Anthology and John Lennard's The Poetry Handbook. It
comes in handy in these newsgroups since like my programming skills,
nobody can even come close:

There is a fine Lady named Julienne
Who feels not a little frustracienne
Owing to spinoza's replies:
They make her give vent to Sighs,

Julienne, in civil discourse, it is not an insult to demur. In the
corporation, for a very good reason that low-level people in
corporations (which all data processing people are) are almost never
given resources by the CEO class to do what needs to be done, a
Leninist rule is applied that cuts civil discourse and demurral off at
arbitrary times. It is understandable that this results in a general
wound, and wounded spirits.

But I simply refuse to acknowledge that here, where no corporate
Leninism need cut off discussion unless people have internalized
corporate slavery, it is insulting to maintain a position with vigor.

What's insulting are people like Richard Heathfield who can't read
code and seizes upon trivia such as malloc.h in order to waste my
time, while enabling bullying. Or Keith Thompson, a zany, who thinks
he can count my errors while not reading my posts, in his sleep as it
were. Or Peter Seebach, who calls me, an Apress colleague of his, a
"moron" to third parties in a way that would get him punched out in a
social event by a real man.

The cowardice of these people is matched by their narcissism in which
they make the stupidest possible errors while expecting forgiveness,
while creating here a permanent record of uncalled for attacks on
professional credibility.

So no, dear lady, I am not insulting you.
>
> Honestly, I'm tired of talking to a brick wall. Let me know when
> you're ready to take me seriously and we may actually be able to chat
> in a civil manner.
>
> > And don't presume even to say that I've "insulted" your gender. That
> > is an utter falsehood. I have not patronized nor talked down to you in
> > the slightest. I am instead arguing for a position: that only an
> > incompetent would have presented a linked list that copies
> > unpredictable data into the nodes. This has nothing to do with gender.
>
> You're in no position to tell me not to defend myself when I feel I'm
> being "bullied" by a "thug", since you're so adamant about taking that
> right for yourself at every turn.

If questioning your conclusions politely and urbanely is bullying you,
then you have a strange definition of bullying. If you were my
supervisor and ordered me to use Richard's technique for creating a
linked list, I'd air my objections briefly, and then do it your way.
But here I am under no such obligation.
```
 0
spinoza1111 (3246)
2/19/2010 7:24:03 AM
```On Feb 19, 9:24=A0am, spinoza1111 <spinoza1...@yahoo.com> wrote:
>
>What's insulting are people like Richard Heathfield who can't read
>code and seizes upon trivia such as malloc.h in order to waste my
>time, while enabling bullying.
>
So I write code using malloc.h. As it turns out, my compiler uses
alloc.h. It takes all of a second to hit the backspace and delete the
"m".
But what happens when we shop the code. It refuses to compile. So
someone who knows C edits it. But that means its got to go into a
different version. Then it hops to machine that takes malloc.h. So its
now in version 3.
The someone finds a bug with the code. He thinks, "obviously, this is
version 3, whilst we were shipped version 1. So let's test the code
with version 1." So he digs out version 1, recompiles, same bug. OK,
the bug was in the original version. As a matter of routine he diffs
the code. Version 1 and version 3 are identical. So maybe what he
thought was version 3 wasn't the real version 3. So he's on the phone,
talking to a guy who left the company who made the original version 2,
trying to find out what went on.
Eventually it will be sorted. But that's the sort of thing that
happens when you have tiny glitches in code.
```
 0
2/19/2010 7:48:59 AM
```spinoza1111 wrote:
<snip>
>
> A better solution (which takes constant time for each element and
> which doesn't "break" if presented with unusually long elements) would
> have been to use pointers to void in each node to point to the
> elements.

And where, pray tell, are you going to *store* your elements?

FCOL.

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
```
 0
rjh (10791)
2/19/2010 9:49:43 AM
```spinoza1111 wrote:
> On Feb 19, 12:48 am, Richard Heathfield <r...@see.sig.invalid> wrote:
>> spinoza1111wrote:
>>
>> <snip lots of same ol' same ol'>
>>
>>>  I have clear
>>> evidence of their incompetence: neither was able to even make a start
>>> on the replace() challenge,
>> Declining to enter your "challenge" shows not incompetence but good
>> judgement.
>
> Why? But I agree. It doesn't show incompetence. Try cowardice.

As the Bandit put it, "That's real good psychology. Why don't you say

If you have technical arguments, post them. If you *are* posting them,
which is just within the bounds of possibility, try posting them without
the drivel and the flame. Then there's a chance they might be spotted.

<nonsense snipped>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
```
 0
rjh (10791)
2/19/2010 9:54:17 AM
```spinoza1111 wrote:
<snip>
> What's insulting are people like Richard Heathfield who can't read
> code and seizes upon trivia such as malloc.h in order to waste my
> time,

When you get even trivial things wrong, it's a potential warning sign
that the rest may be problematic. Having said that, everybody gets
trivial things wrong from time to time. But when you take a long time to
get them right even after they've been pointed out to you, that suggests
even more strongly that the rest of the code is likely to have severe
problems. Reading buggy code wastes *my* time unless I can reasonably
predict that the OP will learn something from my comments. Experience
shows me that this is generally not the case with you. If you want me to
try to find non-trivial errors in your code, I will be glad to oblige if
I can, but only after you've fixed the trivial errors. So if you don't
want me to point out the trivial errors, don't make any.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
```
 0
rjh (10791)
2/19/2010 10:04:49 AM
```On 19 Feb, 07:08, spinoza1111 <spinoza1...@yahoo.com> wrote:
> On Feb 19, 12:48=A0am, Richard Heathfield <r...@see.sig.invalid> wrote:
> > spinoza1111wrote:

<snip>

> > > Heathfield wrote a "linked list tool"
> > > without pointing to data,

<snip>

> [...] my point was that the DATA in the list is the DATA and
> not a link, and nobody with a halfway decent education in data
> structures would have proposed such a stupid design, save, perhaps,
> for a linked list of data elements whose type is simple and fixed in
> length...not a "reusable tool".

Alex Stepanov, the designer of the C++ STL library is untutored in
computer science? The STL is "value based" and copies the data. You
can make the data a pointer if you want to, but you don't have to.

<snip>
```
 0
2/19/2010 1:28:01 PM
```"Richard Heathfield" <rjh@see.sig.invalid> wrote in message
news:euqdnUz6TJAzw-PWnZ2dnUVZ7shi4p2d@bt.com...
> spinoza1111 wrote:
> <snip>
>>
>> A better solution (which takes constant time for each element and
>> which doesn't "break" if presented with unusually long elements) would
>> have been to use pointers to void in each node to point to the
>> elements.
>
> And where, pray tell, are you going to *store* your elements?

In another object? Well, I personally enjoy embedding list nodes directly
into elements:
__________________________________________________________
struct node
{
struct node* next;
};

struct element
{
struct node node;
/* [whatever] */
};
__________________________________________________________

This way I do not have to allocate a seperate node to hold a pointer to the
element. Humm... I think there are basically three ways to do this.

1. Store a pointer to element:

struct node
{
struct node* next;
void* element;
};

2. Store a copy of the element in a node and have the container manage all
the memory:

struct node
{
struct node* next;
void* element;
size_t size;
};

3. Store nothing in a node and let the user "extend" it as nessesary:

struct node
{
struct node* next;
};

I tend to prefer method 3 over anything else because, IMHO, its the most
flexible. For instance, you can easily implement methods 1 and 2:

1.

struct node_ex
{
struct node node;
void* element;
};

2.

struct node_ex
{
struct node node;
void* element;
size_t size;
};

```
 0
no6 (2828)
2/19/2010 1:28:12 PM
```"Nick Keighley" <nick_keighley_nospam@hotmail.com> wrote in message
On 19 Feb, 07:08, spinoza1111 <spinoza1...@yahoo.com> wrote:
> On Feb 19, 12:48 am, Richard Heathfield <r...@see.sig.invalid> wrote:
> > spinoza1111wrote:

<snip>

> > > > Heathfield wrote a "linked list tool"
> > > > without pointing to data,

<snip>

> > [...] my point was that the DATA in the list is the DATA and
> > not a link, and nobody with a halfway decent education in data
> > structures would have proposed such a stupid design, save, perhaps,
> > for a linked list of data elements whose type is simple and fixed in
> > length...not a "reusable tool".

> Alex Stepanov, the designer of the C++ STL library is untutored in
> computer science? The STL is "value based" and copies the data. You
> can make the data a pointer if you want to, but you don't have to.

IMHO, the C++ STL is missing an entire class of fairly important containers:

http://www.boost.org/doc/libs/1_35_0/doc/html/intrusive/intrusive_vs_nontrusive.html

in some usage cases. If I want to push an object onto a list, why does the
damn container have to allocate anything at all? If I know that the object
is only ever going to be on one or two, perhaps three lists, I can embed the
nodes for said lists directly into the object. Of course this has some
caveats, but it gets around unnecessary memory allocations/deallocations in
certain cases.

```
 0
no6 (2828)
2/19/2010 1:34:59 PM
```On 18 Feb, 15:52, spinoza1111 <spinoza1...@yahoo.com> wrote:
> On Feb 18, 9:34=A0pm, Nick Keighley <nick_keighley_nos...@hotmail.com>
> wrote:
>
>
>
>
>
> > On 18 Feb, 09:37, Richard Heathfield <r...@see.sig.invalid> wrote:
>
> > > Nick Keighley wrote:
> > > > On 18 Feb, 08:55, Malcolm McLean <malcolm.mcle...@btinternet.com>
> > > > wrote:
> > > >> On Feb 18, 2:53 am, Julienne Walker <happyfro...@hotmail.com> wrot=
e:
>
> > > >>> I'm afraid I can't imagine how my meaning couldn't be clear: A li=
nked
> > > >>> list of characters or an "array" of characters. These are one-
> > > >>> dimensional data structures, completely linear in concept, and ea=
sy to
> > > >>> visualize even for the most remedial of comp sci students. Combin=
ing
> > > >>> them adds complexity and relatively difficult design decisions.
> > > >> I'm working on DNA data at the moment. Currently I store it as
> > > >> conventional strings.
>
> > > >> However the data is a long list of ACGTs. A human can't possibly r=
> > > >> it all, even small sections look meaningless after a bit. The eye =
is
> > > >> drawn to repeats and chance combinations like 'TAGACAT'.
> > > >> However genomes are not unstructured. Different areas have differe=
nt
> > > >> statistical characteristics, though we don't know exactly what tha=
t
> > > >> means. My job, basically, is to take the raw strings and turn them
> > > >> into something else, something that humans can talk about in a
> > > >> sensible way.
> > > >> So I will need to build extra layers of structure on top of the
> > > >> strings.
>
> > > > are you agreeing or disagreeing?
>
> > > No, I don't think so.
>
> > though interesting, how does the stuff about DNA add to this sub-
>
> Malcolm is describing a real application that needs data structures
> above the level of characters and strings. In fact, it sounds ideal

ok, fair point. DNA analysis would be an application where you
couldn't afford to copy the data.
```
 0
2/19/2010 1:35:45 PM
```In article <slrnhn628c.o3u.usenet-nospam@guild.seebs.net>,
Seebs  <usenet-nospam@seebs.net> wrote:
> This may have gotten buried given that it started in a Nilges thread,
> but it's actually pretty interesting.
>
> There was some discussion of algorithms to perform the task:
> 	Inputs:  target string, replacement string, original string
> 	Output:  a newly-allocated string containing the original
> 	  string with each copy of the target string replaced with the
> 	  replacement string.
>
> Here's a hunk of mine:
>
>         for (count = 0, t = strstr(target, in); t && *t; t = strstr(t, in)) {
>                 ++count;
>                 t += inlen;
>         }
>
> Here's a hunk of another one:
>
> >     ptrIndex1 = strMaster;
> >     while(*ptrIndex1)
> >     {
> >         ptrIndex0 = ptrIndex1;
> >         while (-1)
> >         {
> >             for(;
> >                 *ptrIndex1 && *ptrIndex1 != *strTarget;
> >                 ptrIndex1++);
> >             for(ptrIndex2 = strTarget, ptrIndex3 = ptrIndex1;
> >                 *ptrIndex3
> >                 &&
> >                 *ptrIndex2
> >                 &&
> >                 *ptrIndex3 == *ptrIndex2;
> >                 ptrIndex3++, ptrIndex2++);
> >             if (!*ptrIndex2) break;
> >             ptrIndex1 = ptrIndex3;
> >             if (!*ptrIndex3) break;
> >         }
>
> These hunks are essentially performing the same part of the core loop;
> find the next occurrence of the target string in the original string.
>
> The second one was written by Edward Nilges ("spinoza1111").  He offers
> in its defense the assertion that it's the "best" algorithm.  (Nevermind
> that it's got a bug; the bug could be fixed easily.)
>
> My thinking:
>
> The first is better, not because it's less buggy (that could be fixed), but
> because it's simpler to understand.  It may, or may not, be less efficient.
> However, efficiency will vary widely with input characteristics; for some
> cases, the arguable inefficiencies may be completely irrelevant, while in
> others, they'd be significant.
>
> But you should always write the simpler one first, and wait until you've
> profiled the code and verified that there's a bottleneck, and you know where
> it is, before trying to optimize.  You may, or may not, be able to outperform
> a given library's implementation of strstr().  If you have unusual inputs,
> you have a pretty good shot at it... But it may not be worth it.  The
> complicated example has had at least one bug identified, and there may be
> others.  It's extremely hard to read, partially because of the poor
> naming, and partially because of the counter-idiomatic usage.  But mostly,
> it's a lot more work to write and maintain, and for no known benefit.
>
> It's good to think a little about efficiency, but write for clarity and
> correctness first, so you have a known-working program to check your
> results if you later need to modify it for speed.

Yes ....

Well, I've been having way too much fun(?) with this toy problem,
writing multiple solutions and then trying out different strategies
for packaging tests, measuring performance, and so forth.  Maybe
I should say that I haven't read others' code carefully -- it's
seemed like more fun to get as far as I can myself before looking
at what others have done.

I started out with what I think is a straightforward solution
using string.h functions, scanning the input once to determine
how much space to allocate for output and again to actually build
the output string.  (spinoza1111 may be interested to hear that
it uses recursion.)  I think I spent about an hour getting it
working, for what that's worth.  It passes what I believe to

I then substituted for the string.h functions my own (naive!)
implementations of the same API, so to speak, and that version
worked.

And then I started to get curious about whether a solution that
required lots of malloc'ing to build a linked-list structure
would be faster than one that scanned the input more than once,
as mine does.  So I wrote a couple of solutions that scan the
input only once and build a list -- one that doesn't try too hard
to avoid recomputing string length and one that does.

And then I wrote (many, many versions of) driver code to test
correctness and performance, and started timing things ....

My experiments suggest that the biggest effect on performance is
whether I use the C library functions (fast!) or my substitutes
(slow!).  Scanning only once improves performance with either set
of string-handling functions, though not dramatically; scanning
only once and avoiding recalculating string length also improves
performance, but the difference is most noticeable when using my
string-handling functions.

I've packaged this all up in a way that I think would allow others
to time their implementations -- I've put the string-handling
functions and the replace() function in separate files, so it's
not difficult to experiment with different combinations, and
tests and/or timing tests -- so I'm going to post the whole mess
here ....

And it *is* a bit of a mess still (the code for the scans-only-once
versions has some ugly-hack aspects, for example), but I think I've
had about as much fun as I want to with this problem and am going
to offer up my code for others' amusement, edification, commentary,
or whatever.

Below is output of my timing tests (on a rather old Fedora Linux
system) and all my code.  Anyone wanting to use/adapt the code
should probably pull out the part identified as "file tester.c"
and look for comments including "FIXME".

======== OUTPUT (lightly edited to conserve space) ========

simple version of replace():
scans input twice
does not try to avoid recomputing string lengths
uses C library string functions

performing timing tests (4 repeats)

timing (length 4004, changing 2 occurrences of 2 chars to 2 chars) 20000 times
times (seconds):  0.56 0.54 0.54 0.54

timing (length 4020, changing 10 occurrences of 2 chars to 2 chars) 20000 times
times (seconds):  0.60 0.60 0.60 0.60

timing (length 4100, changing 50 occurrences of 2 chars to 2 chars) 20000 times
times (seconds):  0.91 0.87 0.87 0.87

timing (length 4500, changing 50 occurrences of 10 chars to 10 chars) 20000 times
times (seconds):  0.98 1.24 1.23 0.97

total time = 12.51 seconds

----

simple version of replace():
scans input twice
does not try to avoid recomputing string lengths
uses user-written string functions

performing timing tests (4 repeats)

timing (length 4004, changing 2 occurrences of 2 chars to 2 chars) 20000 times
times (seconds):  0.88 0.85 0.85 0.85

timing (length 4020, changing 10 occurrences of 2 chars to 2 chars) 20000 times
times (seconds):  1.26 1.40 1.29 1.36

timing (length 4100, changing 50 occurrences of 2 chars to 2 chars) 20000 times
times (seconds):  3.```