comp.lang.c - 25 new messages in 8 topics - digest
comp.lang.c
http://groups.google.com/group/comp.lang.c?hl=en
Today's topics:
* Experiment: functional concepts in C - 12 messages, 7 authors
http://groups.google.com/group/comp.lang.c/t/7889fc59043eb32b?hl=en
* Efficency and the standard library - 3 messages, 3 authors
http://groups.google.com/group/comp.lang.c/t/ad9fea19f2f7dd61?hl=en
* rvalue pointer dereference - 2 messages, 2 authors
http://groups.google.com/group/comp.lang.c/t/f153c8b3b4e6d1f7?hl=en
* Portable IEEE754 write routine - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c/t/126301772b46ce23?hl=en
* substring finding problem! - 4 messages, 3 authors
http://groups.google.com/group/comp.lang.c/t/cf9bd97208e0c3a3?hl=en
* Motivation of software professionals - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c/t/21a3fdec4dd53e6a?hl=en
* A bit resistant to disruption - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c/t/a5ddb7c1aa07c7e5?hl=en
* decoding a declaration - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c/t/259df4a3d0342511?hl=en
==============================================================================
TOPIC: Experiment: functional concepts in C
http://groups.google.com/group/comp.lang.c/t/7889fc59043eb32b?hl=en
==============================================================================
== 1 of 12 ==
Date: Wed, Feb 17 2010 7:03 am
From: Hyman Rosen
On 2/16/2010 7:46 PM, Kaz Kylheku wrote:
> main()
> {
> for(big_old_loop)
> {
> heap *h = heap_create();
> func(h);
> heap_dispose(h);
> }
> }
Unless you're very careful, this is an anti-pattern,
and will cause difficult to diagnose errors for this
common singleton pattern:
char *getGlobalFoozleBuffer()
{
static char *buf = calloc(147, 13);
return buf;
}
This is also another example of a sort of memory allocation
which is not, and need not be, freed by the program before
it exits.
== 2 of 12 ==
Date: Wed, Feb 17 2010 7:06 am
From: Hyman Rosen
On 2/16/2010 7:46 PM, Kaz Kylheku wrote:
> main()
> {
> for(big_old_loop)
> {
> heap *h = heap_create();
> func(h);
> heap_dispose(h);
> }
> }
Unless you're very careful, this is an anti-pattern,
and will cause difficult to diagnose errors for this
common singleton pattern:
char *getGlobalFoozleBuffer()
{
static char *buf = calloc(147, 13);
return buf;
}
This is also another example of a sort of memory allocation
which is not, and need not be, freed by the program before
it exits.
== 3 of 12 ==
Date: Wed, Feb 17 2010 8:45 am
From: Keith Thompson
Hyman Rosen <hyrosen@mail.com> writes:
> On 2/16/2010 7:46 PM, Kaz Kylheku wrote:
>> main()
>> {
>> for(big_old_loop)
>> {
>> heap *h = heap_create();
>> func(h);
>> heap_dispose(h);
>> }
>> }
>
> Unless you're very careful,
So be very careful.
> this is an anti-pattern,
> and will cause difficult to diagnose errors for this
> common singleton pattern:
>
> char *getGlobalFoozleBuffer()
> {
> static char *buf = calloc(147, 13);
> return buf;
> }
Why is buf static?
I think what Kaz had in mind is that any memory that needs to be
deallocated on each iteration of the loop is allocated, not via
malloc and friends, but by some other routines that use the "heap"
object created by heap_create(). Since getGlobalFoozleBuffer
calls calloc() directly, the allocated memory won't be affected
by heap_dispose().
The tricky part is knowing which allocations need to survive
throughout the program execution, and which need to be cleaned up
on each iteration of the outer loop. And this can be extended to
multiple levels; the above main() might eventually become a function
in a larger program.
> This is also another example of a sort of memory allocation
> which is not, and need not be, freed by the program before
> it exits.
Maybe. It depends on how global the FoozleBuffer really is.
--
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"
== 4 of 12 ==
Date: Wed, Feb 17 2010 9:09 am
From: Seebs
On 2010-02-17, Richard Heathfield <rjh@see.sig.invalid> wrote:
> So you'd have caused us the same problem that $PROGRAMMING_TEAM did.
> After all, at the time they wrote the code, they had no reason to
> suspect a new pass; this was not added until some time after completion
> of the original program.
Maybe. My guess is that I wouldn't have, because the unfreed allocations
would all be of the form:
if (!table)
table = malloc(...);
and adding passes would have no effect. The only cases I can think of where
I have unconditional allocations which aren't freed, they lead to something
to the effect of:
execv(...);
fprintf(stderr, "exec failed: %s\naborting.\n", strerror(errno));
exit(EXIT_FAILURE);
Or, probably in some cases, there's a single giant object with a foo_free()
defined which you could free at the end of each pass.
Hmm. Okay, I found an exception. I have a typical Unix-style filter
lying around which does not deallocate its buffer and list of offsets into
the buffer. On the other hand, because it's a filter, it's *already*
looping, so it wouldn't make much sense to try to invoke it in a loop. If
you did need to, though, it'd be pretty easy.
-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!
== 5 of 12 ==
Date: Wed, Feb 17 2010 10:00 am
From: Kaz Kylheku
On 2010-02-17, Ersek, Laszlo <lacos@ludens.elte.hu> wrote:
>> Maximal portability, the kind where we pretend we write a single body of
>> source code without conditionl compilation while pretending we programming
>> for an incapable, broken platform, is only an obsession of a few dull minds.
>
> Please don't. This is also an economically feasible approach, only with
> very different economic factors.
Sure, you can always put together a portability programming tournament,
where everyone pays to enter, and the winner fetches a monetary prize.
The same economic factors as in poker, golf, competitive road running,
etc.
In actual software, maximal portabilty is the enemy of portability.
>> That should come as no surprise: it requires a lower level reasoning than
>> doing a crossword puzzle from the newspaper.
>
> Ignoring for a moment that this is a factually incorrect deliberate
> offense, isn't it the general understanding that reasoning and code and
> development processes that require less mental strain are easier to keep
> bug-free?
I didn't say anything about less work. A lower /level/ of reasoning
doesn't translate to less work.
For instance, throughout this thread you've been advocating the addition
of /completely unnecessary/ code (bearing unnecessary risk) to a program
for the sake of portability.
How can it ever be less straining to add more code, compared to
not adding it at all?
Any monkey can read a couple of ISO standards a few times over again and
learn to spot nonportability in code.
``Hey look, that text stream was closed and a few lines before it, it's
clear that the last character written wasn't a newline! I'm so smart!''
== 6 of 12 ==
Date: Wed, Feb 17 2010 10:20 am
From: Zarquon
Richard Heathfield wrote:
> Richard Tobin wrote:
>> In article <20100216180746.241@gmail.com>,
>> Kaz Kylheku <kkylheku@gmail.com> wrote:
>>
>>> Only a complete fool argues against a statement about ``one action'',
>>> without any agreed-upon definition of ``action'' anywhere in sight.
>>
>> My aim was to enlighten the poster, not to win an argument by
>> pedantry. If that's being a complete fool, I can put up with it.
>
> Only a complete fool makes blanket statements about what only a complete
> fool would do, so I wouldn't pay too much attention if I were you.
There are a number of people who I think of as complete fools, who take
every opportunity to paint Richard Heathfield with the brush of
"complete fool", but since I regard them as complete fools, I can
completely ignore their attempts to undermine Richard's credibility.
To find Richard calling himself a complete fool is rather puzzling, as
he otherwise scores fairly high on my credibility meter. If I believe
him, then he has no credibility and if he has no credibility then I
don't believe him. But if I don't believe him then he does have
credibility, so I should believe him.
Help! The paradox is melting my brain!
--
Usenet is an opportunity to empathize with people. If you can't
feel the other person's pain, then you're not inflicting enough.
-- Eb Oesch
== 7 of 12 ==
Date: Wed, Feb 17 2010 10:24 am
From: Richard Heathfield
Zarquon wrote:
> Richard Heathfield wrote:
>> Richard Tobin wrote:
>>> In article <20100216180746.241@gmail.com>,
>>> Kaz Kylheku <kkylheku@gmail.com> wrote:
>>>
>>>> Only a complete fool argues against a statement about ``one action'',
>>>> without any agreed-upon definition of ``action'' anywhere in sight.
>>>
>>> My aim was to enlighten the poster, not to win an argument by
>>> pedantry. If that's being a complete fool, I can put up with it.
>>
>> Only a complete fool makes blanket statements about what only a
>> complete fool would do, so I wouldn't pay too much attention if I were
>> you.
>
> There are a number of people who I think of as complete fools, who take
> every opportunity to paint Richard Heathfield with the brush of
> "complete fool", but since I regard them as complete fools, I can
> completely ignore their attempts to undermine Richard's credibility.
Just to set the record straight, I don't truly think of Kaz as a
complete fool. In fact, I regard him very highly, although (like mine)
his mastery of tact and diplomacy still has a few weak spots. That is
not to say that I always agree with his technical opinions, but where we
disagree I generally find myself looking hard at my own views, because
Kaz has a good track record of being right.
> To find Richard calling himself a complete fool is rather puzzling,
My sense of humour is indeed rather strange.
<snip>
> Help! The paradox is melting my brain!
Easily fixed - just accept that it's a paradox, and therefore an
inadequate description of the real situation.
--
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
== 8 of 12 ==
Date: Wed, Feb 17 2010 10:34 am
From: Kaz Kylheku
["Followup-To:" header set to comp.lang.c.]
On 2010-02-17, Richard Tobin <richard@cogsci.ed.ac.uk> wrote:
> In article <20100216180746.241@gmail.com>,
> Kaz Kylheku <kkylheku@gmail.com> wrote:
>
>>Only a complete fool argues against a statement about ``one action'',
>>without any agreed-upon definition of ``action'' anywhere in sight.
>
> My aim was to enlighten the poster, not to win an argument by
> pedantry. If that's being a complete fool, I can put up with it.
Sorry, I that wasn't aimed at you. :)
== 9 of 12 ==
Date: Wed, Feb 17 2010 10:46 am
From: Ertugrul Söylemez
Kaz Kylheku <kkylheku@gmail.com> wrote:
> On 2010-02-16, Ertugrul Söylemez <es@ertes.de> wrote:
> > Hyman Rosen <hyrosen@mail.com> wrote:
> >
> >> On 2/16/2010 3:42 PM, Ertugrul Söylemez wrote:
> >> > It is a bug, but some people tolerate it, some don't. What the
> >> > operating system does here is not called resource management, but
> >> > fault tolerance. It should be designed not to fail on
> >> > programming errors.
> >>
> >> What a bizarre notion. What happens to the resources of a program
> >> when the program exits is defined by the operating system. Relying
> >> on OS-defined behavior in your program is not an error. Performing
> >> time-wasting activity on abstract grounds of illusory correctness,
> >> on the other hand, is an error.
> >
> > You're showing that you are an irresponsible programmer. C and
> > Cobol are about the only languages in wide-spread use, which even
> > allow that kind of carelessness. Modern languages are even designed
> > to prevent you from being stupid. But obviously you want to be
> > stupid.
>
> What modern languages would those be? I suspect you could not name one
> such that you are not wrong.
All languages with an automatic garbage collector. There are even
languages, which implement that "tag stack" I mentioned earlier
directly, like C# with its 'using' directive.
> > Relying on operating system fault tolerance is wrong and most good
>
> It's not fault tolerance but resource management. You are pitifully
> wrong in your other posting.
>
> Relying on this is no more wrong than relying on a TCP/IP stack,
> graphics display, or DMA transfers.
TCP/IP stack, graphics display and DMA transfers are functionality.
What you can "resource management" prevents the system from crashing,
just because some programmers write wrong code. That's not
functionality, it's fault tolerance.
> > It's no
> > programmers will agree, at the very least because they want their
> > programs to be portable
>
> Programmers who get paid for a living want their programs to be
> portable in a way that is /economically/ relevant, balanced with other
> requirements.
>
> Maximal portability, the kind where we pretend we write a single body
> of source code without conditionl compilation while pretending we
> programming for an incapable, broken platform, is only an obsession of
> a few dull minds.
What the hell is wrong with freeing resources? It takes twenty seconds
to write the code to do it. The code itself uses at most one or two
seconds to execute and guarantees correctness.
We all know how well most commercial programs work. If that is your
"enconomically relevant, balanced" portability, then commercial
application development is in a bad state.
Serious programmers won't even argue about this topic. We're talking
about something as trivial as freeing allocated resources. He will just
do it and that's it. After all, that's what he has learned from books
and school anyway.
> > Modularity is the key to maintainability, and if you disagree here,
> > you're just ridiculous and nobody will take you seriously anyway.
>
> Without automatic storage managament, there is no real modularity.
> Modules are coupled together by the distributed responsibility of
> memory management. It creeps into all the interfaces: who allocates
> what and who will free it.
>
> It's laughable to advocate explicit storage deallocation and
> modularity in the same breath.
Indeed. Having a system, which guarantees correctness, is important in
such a setting.
Greets
Ertugrul
--
nightmare = unsafePerformIO (getWrongWife >>= sex)
http://blog.ertes.de/
== 10 of 12 ==
Date: Wed, Feb 17 2010 10:53 am
From: Seebs
On 2010-02-17, Ertugrul Söylemez <es@ertes.de> wrote:
> What the hell is wrong with freeing resources? It takes twenty seconds
> to write the code to do it. The code itself uses at most one or two
> seconds to execute and guarantees correctness.
Well, no.
1. It doesn't guarantee correctness. I already provided an example where
it did not guarantee correctness, because a program could run out of memory
if it ran long enough, even though at any given point, if it exited, it
would free everything.
2. It can take a lot more than twenty seconds to write the code to do it.
3. It can take a lot more than one or two seconds to execute, especially
on slower hardware.
There exist cases where there are good reasons not to do it. They may be
specialized cases, they may not be all that common...
Here's the thing. If you want to argue that it's a good idea, and should be
assumed as a default strategy and used until someone has a concrete and
specific reason not to do it, great! I agree totally.
When you start making blanket assertions, or calling programs which rely on
a 100% documented and guaranteed aspect of their operating environment
"incorrect", though, you undermine your position. The net result is that not
only are people not persuaded of what you're saying, they're persuaded against
the general practice of freeing allocated resources, because they conclude
that the people advocating it are fanatics who don't understand engineering
tradeoffs.
> Serious programmers won't even argue about this topic.
Does preemptively insulting people for disagreeing with you usually work
in your culture? In mine it's often taken to be a sign of lacking persuasive
arguments.
-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!
== 11 of 12 ==
Date: Wed, Feb 17 2010 11:38 am
From: Keith Thompson
Seebs <usenet-nospam@seebs.net> writes:
> On 2010-02-17, Ertugrul Söylemez <es@ertes.de> wrote:
>> What the hell is wrong with freeing resources? It takes twenty seconds
>> to write the code to do it. The code itself uses at most one or two
>> seconds to execute and guarantees correctness.
>
> Well, no.
>
> 1. It doesn't guarantee correctness. I already provided an example where
> it did not guarantee correctness, because a program could run out of memory
> if it ran long enough, even though at any given point, if it exited, it
> would free everything.
> 2. It can take a lot more than twenty seconds to write the code to do it.
> 3. It can take a lot more than one or two seconds to execute, especially
> on slower hardware.
4. Even if it takes only one or two seconds, that overhead might
be unacceptable. If my text editor takes one or two seconds to
terminate after I tell it to exit, I'll be annoyed. If a command
that I execute a few hundred times in a loop takes one or two seconds
to exit, I'll probably have to find a different way to accomplish
my task.
--
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"
== 12 of 12 ==
Date: Wed, Feb 17 2010 11:46 am
From: Kaz Kylheku
On 2010-02-17, Keith Thompson <kst-u@mib.org> wrote:
> Hyman Rosen <hyrosen@mail.com> writes:
>> On 2/16/2010 7:46 PM, Kaz Kylheku wrote:
>>> main()
>>> {
>>> for(big_old_loop)
>>> {
>>> heap *h = heap_create();
>>> func(h);
>>> heap_dispose(h);
>>> }
>>> }
>>
>> Unless you're very careful,
>
> So be very careful.
>
>> this is an anti-pattern,
>> and will cause difficult to diagnose errors for this
>> common singleton pattern:
>>
>> char *getGlobalFoozleBuffer()
>> {
>> static char *buf = calloc(147, 13);
>> return buf;
>> }
>
> Why is buf static?
Because this is a singleton pattern; each call to this function
is expected to yield the same object.
> I think what Kaz had in mind is that any memory that needs to be
> deallocated on each iteration of the loop is allocated, not via
> malloc and friends, but by some other routines that use the "heap"
> object created by heap_create(). Since getGlobalFoozleBuffer
> calls calloc() directly, the allocated memory won't be affected
> by heap_dispose().
But originally, /all/ functions call the allocator directly, just
like this function. When we are refactoring the program to use the heap
allocator we have to distinguish this case, and perhaps have it do this:
static char *buf = heap_calloc(global_heap, 147, 13);
But this is a simple case where the data flow is simple: the source of
the dynamic object and its destination static variable are in the same
full expression. This is not always the case in a real program. The
calloc call may be in some generic routine that is called (perhaps
through a number of levels of call nesting), such that its return value
is sometimes stored in a static variable and sometimes not.
So then the whole function chain needs to pass down the allocation
context.
Finding such cases in a large program is difficult, and so this can
add significant risk.
This boils down to the problem of various degrees of incompleteness of
the simulation of re-running a program. To run a C program, we must
initialize its static variables to their correct intial values specified
in the source code (among lots of other things). Since we have not done
that, we get the old values of the static variables, which may contain
dangling pointers.
The first solution I might reach for to solve this would be dynamic linking,
which is available on a number of important platforms, and provides
reinitialization of statics (if you unload a library and then re-load,
it gets new statics which are properly initialized). On platforms that
support dynamic linking, it can be considered the preferred tool
for turning standa-alone programs into components of other programs.
There is likely going to be some considerable overhead in doing the
unload and reloading, since it involves mapping and unmapping memory.
A less easy, though more portable solution which has other advantages
too, is to identify the static variables of program foo and factor them
out into a ``struct foo_globals''. Then we can initialize them before
re-running the program. This is a lot of work, but at least it's
largely mechanical: looking for all file scope and block scope static
definitions.
A much less portable solution, though seemingly easy, would be to get
help from a scriptable linker like GNU ld. The static objects in
program foo could be put into custom .foo.bss and .foo.data section. On
program startup, we stash a copy of .foo.data somewhere. Prior to each
call to the foo_main, we reinitialize the .foo.data section with the
stashed copy, and clear .foo.bss to all zero bits.
==============================================================================
TOPIC: Efficency and the standard library
http://groups.google.com/group/comp.lang.c/t/ad9fea19f2f7dd61?hl=en
==============================================================================
== 1 of 3 ==
Date: Wed, Feb 17 2010 8:48 am
From: Tim Streater
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
>> they hadn't asked for and that was pretty useless once the guy had left.
>
> 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
> elsethread: they self-selected into programming because they had
> reading difficulties, especially in reading literature.
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.
>> Yes, I know about this thanks very much. But any society having an
>> 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
== 2 of 3 ==
Date: Wed, Feb 17 2010 9:02 am
From: Seebs
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!
== 3 of 3 ==
Date: Wed, Feb 17 2010 10:44 am
From: Malcolm McLean
On Feb 17, 7:02 pm, 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. 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.)
>
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".
==============================================================================
TOPIC: rvalue pointer dereference
http://groups.google.com/group/comp.lang.c/t/f153c8b3b4e6d1f7?hl=en
==============================================================================
== 1 of 2 ==
Date: Wed, Feb 17 2010 8:51 am
From: Keith Thompson
Ted DeLoggio <tdeloggio@gmail.com> writes:
> I do not understand the meaning of the parentheses used when
> dereferencing the char pointer named "s" in the following program:
>
> #include <stdio.h>
>
> #define MAX 50
>
> int main(void)
> {
> char str[MAX];
> char *s;
> char c;
>
> printf("Enter a string < %d characters:", MAX);
> fgets(str, MAX, stdin);
>
> s = str;
> c = *(s);
> printf("s = %c\n", c);
> }
>
>
> If I change the line:
> c = *(s);
>
> to:
>
> c = *s;
>
> The program compiles without warning and runs OK with the following
> compiler flags (maybe OT):
>
> gcc -std=c99 -pedantic -Wall -Wextra deref.c
You didn't mention what happens if you *don't* change the line.
Presumably it behaves exactly the same way.
> Are the parentheses necessary? Section 6.5.3.2 of ISO/IEC 9899:TC2
> seems to indicate that the result of the dereference without
> parentheses would be an lvalue, perhaps this is related?
The parentheses are useless. C99 6.5.3.2 doesn't imply what you
think it does; the expression is an lvalue with or without the
parentheses (see C99 6.5.1p5), but it's not being used in a context
that requires an lvalue so that doesn't matter.
Incidentally, there's a newer post-C99 draft that includes all three
Technical Corrigenda:
<http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf>.
--
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"
== 2 of 2 ==
Date: Wed, Feb 17 2010 11:50 am
From: Kaz Kylheku
On 2010-02-17, Ted DeLoggio <tdeloggio@gmail.com> wrote:
> I do not understand the meaning of the parentheses used when
> dereferencing the char pointer named "s" in the following program:
A parenthesized expression is a primary expression, having
the highest precedence.
An identifier expression like s is already primary expression.
Parentheses around a primary expression do nothing; they derive a
primary expression from what is already a primary expression,
without changing any aspect of its meaning (such as its type,
whether it is an lvalue, whether it is a constant expression, ...).
==============================================================================
TOPIC: Portable IEEE754 write routine
http://groups.google.com/group/comp.lang.c/t/126301772b46ce23?hl=en
==============================================================================
== 1 of 1 ==
Date: Wed, Feb 17 2010 9:04 am
From: Malcolm McLean
Here it is. Many thanks to all who helped, especially Michael on whose
contribution the code is mainly based.
The idea is to write a float in binary IEEE format, reagrdless of the
native representation in the machine you are on.
I've only access to a Windows PC at the moment, so I'd be grateful if
people could test it on other architectures, especially non-IEEE
native floating point units. Particularly I'm not sure about the
denormalised numbers - my printf seems to think they are identical to
zero so I'm not sure if I'm dropping precision.
int fwriteieee754(double x, FILE *fp, int bigendian)
{
int shift;
unsigned long sign, exp, hibits, hilong, lowlong;
double fnorm, significand;
int expbits = 11;
int significandbits = 52;
/* zero (can't handle signed zero) */
if(x == 0)
{
hilong = 0;
lowlong = 0;
goto writedata;
}
/* infinity */
if(x > DBL_MAX)
{
hilong = 1024 + ((1<<(expbits-1)) - 1);
hilong <<= (31 - expbits);
lowlong = 0;
goto writedata;
}
/* -infinity */
if(x < -DBL_MAX)
{
hilong = 1024 + ((1<<(expbits-1)) - 1);
hilong <<= (31-expbits);
hilong |= (1 << 31);
lowlong = 0;
goto writedata;
}
/* NaN - dodgy because many compilers optimise out this test, but
*there is no portable isnan() */
if(x != x)
{
hilong = 1024 + ((1<<(expbits-1)) - 1);
hilong <<= (31 - expbits);
lowlong = 1234;
goto writedata;
}
/* get the sign */
if(x < 0) {sign = 1; fnorm = -x;}
else {sign = 0; fnorm = x;}
/* get the normalized form of f and track the exponent */
shift = 0;
while(fnorm >= 2.0) { fnorm /= 2.0; shift++; }
while(fnorm < 1.0) { fnorm *= 2.0; shift--; }
/* check for denormalized numbers */
if(shift < -1022)
{
while(shift <-1022) {fnorm /= 2.0; shift++;}
shift = -1023;
}
else
fnorm = fnorm - 1.0; /* take the significant bit off mantissa */
/* calculate the integer form of the significand */
/* hold it in a double for now */
significand = fnorm * ((1LL<<significandbits) + 0.5f);
/* get the biased exponent */
exp = shift + ((1<<(expbits-1)) - 1); /* shift + bias */
/* put the data into tweo longs (for convenience) */
hibits = (long) (significand / 4294967296);
hilong = (sign << 31) | (exp << (31-expbits) ) | hibits;
lowlong = (long) (significand - hibits * 4294967296);
writedata:
/* write the bytes out to the stream */
if(bigendian)
{
fputc( (hilong >> 24) & 0xFF, fp);
fputc( (hilong >> 16) & 0xFF, fp);
fputc( (hilong >> 8) & 0xFF, fp);
fputc( hilong & 0xFF, fp);
fputc( (lowlong >> 24) & 0xFF, fp);
fputc( (lowlong >> 16) & 0xFF, fp);
fputc( (lowlong >> 8) & 0xFF, fp);
fputc( lowlong & 0xFF, fp);
}
else
{
fputc( lowlong & 0xFF, fp);
fputc( (lowlong >> 8) & 0xFF, fp);
fputc( (lowlong >> 16) & 0xFF, fp);
fputc( (lowlong >> 24) & 0xFF, fp);
fputc( hilong & 0xFF, fp);
fputc( (hilong >> 8) & 0xFF, fp);
fputc( (hilong >> 16) & 0xFF, fp);
fputc( (hilong >> 24) & 0xFF, fp);
}
return ferror(fp);
}
==============================================================================
TOPIC: substring finding problem!
http://groups.google.com/group/comp.lang.c/t/cf9bd97208e0c3a3?hl=en
==============================================================================
== 1 of 4 ==
Date: Wed, Feb 17 2010 9:16 am
From: Seebs
On 2010-02-17, fedora <no_mail@invalid.invalid> wrote:
> Thanks Ben! I didn't use stdlib functions because i wanted to how
> easy/difficult it would be to write my own. also spinoza didn't accept
> program that called function in string.h.
Unless you're expecting to spend most of your programming career working
for people who have major obsessive problems with using technology in ways
that generally work, because of personal grudges never adequately explained,
I would suggest that perhaps what Nilges accepts or doesn't accept should
not be a component of any technical decision, ever.
> About plugging in my own versions, do you mean writing routines with the
> same name so that at linking the linker finds my lib first and plug it in?
> but i read somewhere that using ansi c's namespace and relying on linker is
> all undefined and gcc can replace calls to stdlib functions with inline code
> so bypassing my code too... but i'll try it.
The obvious way to do it would be:
size_t
callstrlen(const char *s) {
#ifdef ME
/* your code here */
#else
return strlen(s);
0 Comments:
Post a Comment
Subscribe to Post Comments [Atom]
<< Home