Saturday, February 13, 2010

comp.lang.c - 25 new messages in 5 topics - digest

comp.lang.c
http://groups.google.com/group/comp.lang.c?hl=en

comp.lang.c@googlegroups.com

Today's topics:

* The C FAQ - 6 messages, 3 authors
http://groups.google.com/group/comp.lang.c/t/b75c0ae09abf3345?hl=en
* Motivation of software professionals - 10 messages, 4 authors
http://groups.google.com/group/comp.lang.c/t/21a3fdec4dd53e6a?hl=en
* void * arithmetic - 3 messages, 3 authors
http://groups.google.com/group/comp.lang.c/t/a33b3b6b3dba34c8?hl=en
* Efficency and the standard library - 5 messages, 5 authors
http://groups.google.com/group/comp.lang.c/t/ad9fea19f2f7dd61?hl=en
* A bit resistant to disruption - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c/t/a5ddb7c1aa07c7e5?hl=en

==============================================================================
TOPIC: The C FAQ
http://groups.google.com/group/comp.lang.c/t/b75c0ae09abf3345?hl=en
==============================================================================

== 1 of 6 ==
Date: Sat, Feb 13 2010 1:29 pm
From: Seebs


On 2010-02-13, Alan Curry <pacman@kosh.dhis.org> wrote:
> In article <slrnhndmbn.2el.usenet-nospam@guild.seebs.net>,
> Seebs <usenet-nospam@seebs.net> wrote:
>|What this ends up doing is allowing me to intercept every system call that
>|deals with the filesystem and is affected by privileges, and act as though
>|you had root privileges, or at least, make it look as though it acted as

> Somebody already did this. It's called fakeroot. Terrible duplication of
> effort if you reinvented it from scratch

We used to use fakeroot. It was unsuitable for our purposes in a number
of ways.

Among them:

1. Not much persistency. Fakeroot's good at handling a single build run
which completes in a few minutes. Our system has to handle doing dozens or
hundreds. Over a period of months.
2. Extreme vulnerability to database corruption if anything is changed
outside of it.
3. No real database to speak of; on exit, it writes a flat file list of
plain text data, and it can slurp that back in.
4. No file name tracking. This makes it harder to detect other errors.
5. Can get confused enough to, say, report that a directory is a plain
file, or vise versa.
6. Occasionally crashes, breaking programs relying on it.
7. Also, in default configuration, leaves shared memory segments allocated
and not cleaned up.

There were other issues. After careful study, we concluded that it would be
best to write one from scratch, from the ground up, addressing many of these
concerns.

Mine's called pseudo, and we're currently doing a code clean-up pass before
making it more widely available under some GPL variant. Key differences:

* Tracks file names in nearly-all cases. (You can get past it, but it is
very good at finding out file names.)
* Persistent database using sqlite3 maintained by the daemon.
* Database tracks both names and dev/inode pairs.
* Server does consistency checks and correctly handles cases such as, say,
a database entry which has the same inode as an incoming query, but has
a necessarily-incompatible type (e.g., is tagged as a directory but is
not).
* Client code can automatically restart the server if it goes away or isn't
available, so server doesn't need to be encouraged to stay running for a
long time just because a build might be slow.
* Can log every filesystem action it sees.

We used fakeroot in production systems for a couple of product releases.
Typically, if you loaded things up (say, started and stopped it dozens of
times during an extended build series), sooner or later, it would start
yielding garbage like claiming that a plain file was a directory, or giving
arbitrarily wrong results for files, or lose parts of the recorded state.
Or just crash. On average, if you were using the build system heavily, you'd
hit some kind of "fakeroot failed, you have to re-install all target packages"
thing about once or twice a week.

Since we put in pseudo, we've had one customer bug (which was in an area where
we'd decided to not fully implement something in the first release). When the
bug was reported, the report could tell us what file name pseudo expected to
see for a given file, and what file name had shown up, and why this was
surprising, allowing us to fix the bug in five minutes rather than spending
hours trying to figure out when that inode had been created or freed. We've
had a handful of bugs discovered internally during development, but as of this
writing, I have out for review fixes for the last bugs we are aware of that
have ever caused any kind of failure. (In fact, the last bugs we are aware
of. There have been bugs that didn't cause any failures, because pseudo is
extremely aggressive about sanity-checking its results.)

Basically, if you just look at the time that our developers lost to project
directories that got harmed by fakeroot failures, we've gotten the time I put
back on this returned to us about five-fold since I started.

I would not call it a waste of effort. We did research the alternatives
before trying this, and none of them were a good fit for our usage scenario.

(Relevance, such as it is: It's worth noting that there IS such a thing as
a time to rebuild something that already exists.)

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


== 2 of 6 ==
Date: Sat, Feb 13 2010 1:41 pm
From: lacos@ludens.elte.hu (Ersek, Laszlo)


In article <slrnhne63b.lvb.usenet-nospam@guild.seebs.net>, Seebs <usenet-nospam@seebs.net> writes:
> On 2010-02-13, Ersek, Laszlo <lacos@ludens.elte.hu> wrote:
>> I was calling your pointer-to-function named real_open "orig_open". How
>> do you initialize it? :)
>
> With a magic bit of code using "dlsym()" to look up symbols in other
> libraries, relying on a feature where it's possible to specify "give me
> the next version after the one you already found". :)

Yes, yes, that's RTLD_NEXT as a handle, as I wrote previously (check
it). Or perhaps you use something more sophisticated, but that's not
what I'm after.

How do you assign the value returned by dlsym() to a
pointer-to-function? :)

Cheers,
lacos


== 3 of 6 ==
Date: Sat, Feb 13 2010 1:48 pm
From: lacos@ludens.elte.hu (Ersek, Laszlo)


In article <slrnhne6lp.lvb.usenet-nospam@guild.seebs.net>, Seebs <usenet-nospam@seebs.net> writes:

> Mine's called pseudo, and we're currently doing a code clean-up pass before
> making it more widely available under some GPL variant.

Thank you.
lacos


== 4 of 6 ==
Date: Sat, Feb 13 2010 1:49 pm
From: Seebs


On 2010-02-13, Ersek, Laszlo <lacos@ludens.elte.hu> wrote:
> Yes, yes, that's RTLD_NEXT as a handle, as I wrote previously (check
> it). Or perhaps you use something more sophisticated, but that's not
> what I'm after.

> How do you assign the value returned by dlsym() to a
> pointer-to-function? :)

=

Seriously, it's that simple. :P

Actually, it's sorta fancy. What I have is a bunch of declarations
like:

int (*real_open)(const char *, int, ...) = dummy_open;
and then a table that looks like

[...]
{ "open",
(int (**)(void)) &real_open,
(int (*)(void))dummy_open,
(int (*)(void))wrap_open },
[...]
{ NULL, NULL, NULL, NULL }

and then:

if (*pseudo_functions[i].real == pseudo_functions[i].dummy) {
int (*f)(void);
f = dlsym(RTLD_NEXT, pseudo_functions[i].name);
if (error_check) {
/* warn about the error */
} else {
*pseudo_functions[i].real = f;
}
}

Once that's done, real_open is a pointer of the correct type that points to
the correct function. Since function pointers may be safely cast to and
from other types, this is *almost* safe. Strictly speaking, I suspect that
I ought to be converting the pointer to the correct type, and storing the
correct types in the table, but that turns out to be very hard to write
clearly, and I'm reasonably confident that any system where dlsym works will
be one where the type punning works too.

-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 6 ==
Date: Sat, Feb 13 2010 3:15 pm
From: Phred Phungus


Andrew Poelstra wrote:
> On 2010-02-12, Richard Heathfield <rjh@see.sig.invalid> wrote:
>> Andrew Poelstra wrote:
>>> On 2010-02-12, Richard Heathfield <rjh@see.sig.invalid> wrote:
>>>> Given that, even now, there are current production systems - not very
>>>> many, I grant you, but still *some - that rely on MS-DOS and which are
>>>> still being maintained and developed, two of the other three adjectives
>>>> are open to question, too. As for "old", the MS-DOS-specific material is
>>>> almost certainly about as old as much of the other material. Steve
>>>> Summit did do some C99-related updates a few years ago, but not many.
>>>>
>>> I would suspect, though, that the people tasked with
>>> maintaining those DOS machines are not brand spanking
>>> new C programmers who need (or want) to read the FAQ.
>>>
>>> Jacob's point is that the "real" brand spanking new C
>>> programmers will see the DOS questions, remember from
>>> their Java courses that all Old things are Bad, then
>>> end up posting here anyway (or worse, doing their own
>>> thing).
>> In one sense, your reply is perfectly justified.
>>
>
> Well, I realized after the fact that if I replaced "though"
> with "however" and "Bad" with "Evil", I could have been rid
> of those pesky spaces.
>
> But I should add that as near as I can tell, there aren't a
> whole lot of people coming here with silly questions caused
> by mistrust of the FAQ. Perhaps merely being Usenet in 2010
> is enough to be inaccessible to most newbies?
>
>
> Andrew
>

I haven't read this thread carefully, but I think DOS lives on in
windows, if only because that's the way it exists in the minds of many
windows users.

If you told someone to "pull up a dos window," would that sentence be
more precise if one said, "I need you to pull up a windows window."

If one wants to use gnu development tools on the windows platform, he
can go the cygwin route. This option didn't work well for me, probably
because I couldn't do crap off a bash prompt when I tried this. A big
part of *nix is using the command effectively and quickly. Those of us
who grew up in shadow of Microsoft will find a steep learning curve here.

Alternatively, he can use a DOS prompt that begins life as a link. This
environment accepts the DOS commands that guys like me were using in
1983. So the shell has subsumed DOS, but with smoke and mirrors, it
seems like DOS to me.

Now that I'm finally on a pimped-out linux terminal, I won't miss DOS a bit.
--
fred


== 6 of 6 ==
Date: Sat, Feb 13 2010 4:40 pm
From: lacos@ludens.elte.hu (Ersek, Laszlo)


In article <slrnhne7ps.70j.usenet-nospam@guild.seebs.net>, Seebs <usenet-nospam@seebs.net> writes:
> On 2010-02-13, Ersek, Laszlo <lacos@ludens.elte.hu> wrote:
>> Yes, yes, that's RTLD_NEXT as a handle, as I wrote previously (check
>> it). Or perhaps you use something more sophisticated, but that's not
>> what I'm after.
>
>> How do you assign the value returned by dlsym() to a
>> pointer-to-function? :)
>
> =
>
> Seriously, it's that simple. :P
>
> Actually, it's sorta fancy. What I have is a bunch of declarations
> like:

I'll insert [1], [2] etc below.

>
> int (*real_open)(const char *, int, ...) = dummy_open;
> and then a table that looks like
>
> [...]
> { "open",
> [1] (int (**)(void)) &real_open,
> [2] (int (*)(void))dummy_open,
> (int (*)(void))wrap_open },
> [...]
> { NULL, NULL, NULL, NULL }
>
> and then:
>
> if (*pseudo_functions[i].real == pseudo_functions[i].dummy) {
> int (*f)(void);
> [3] f = dlsym(RTLD_NEXT, pseudo_functions[i].name);
> if (error_check) {
> /* warn about the error */
> } else {
> [4] *pseudo_functions[i].real = f;
> }
> }
>
> Once that's done, real_open is a pointer of the correct type that points to
> the correct function. Since function pointers may be safely cast to and
> from other types, this is *almost* safe. Strictly speaking, I suspect that
> I ought to be converting the pointer to the correct type, and storing the
> correct types in the table, but that turns out to be very hard to write
> clearly, and I'm reasonably confident that any system where dlsym works will
> be one where the type punning works too.

In my opinion, [1] might have an alignment problem theoretically (C90
6.3.4 "Cast operators" p6, C99 6.3.2.3 "Pointers" p7); [2] is conformant
if dummy_open and wrap_open are cast back to the correct
pointer-to-function type before called (C90 6.3.4 p7, C99 6.3.2.3 p8).
I guess [4] might store garbage through the incompatible pointer,
theoretically.

[3] is undefined under ISO C, but it's interesting to compare the
SUSv[234] specifications of dlsym():

http://www.opengroup.org/onlinepubs/007908799/xsh/dlsym.html

http://www.opengroup.org/onlinepubs/009695399/functions/dlsym.html

http://www.opengroup.org/onlinepubs/9699919799/functions/dlsym.html
http://www.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_12_03

The example of the C90-based SUSv2 simply casts the (void *) value
returned by dlsym() to a pointer-to-function type.

SUSv3 (based on C99) notes in the Rationale that

----v----
The ISO C standard does not require that pointers to functions can be
cast back and forth to pointers to data. Indeed, the ISO C standard does
not require that an object of type void * can hold a pointer to a
function. Implementations supporting the XSI extension, however, do
require that an object of type void * can hold a pointer to a function.
The result of converting a pointer to a function into a pointer to
another data type (except void *) is still undefined, however.
----^----

Thus it requires *conversion*, but then it goes on and (supposedly to
suppress a mandatory warning:)

----v----
Note that compilers conforming to the ISO C standard are required to
generate a warning if a conversion from a void * pointer to a function
pointer is attempted as in:

fptr = (int (*)(int))dlsym(handle, "my_function");
----^----

simply accesses the function pointer as if it was a pointer to void:

----v----
int (*fptr)(int);

*(void **)(&fptr) = dlsym(handle, "my_function");
----^----

SUSv4 finally covers both conversion and representation explicitly:

----v----
2.12.3 Pointer Types

All function pointer types shall have the same representation as the
type pointer to void. Conversion of a function pointer to void * shall
not alter the representation. A void * value resulting from such a
conversion can be converted back to the original function pointer type,
using an explicit cast, without loss of information.

Note:
The ISO C standard does not require this, but it is required for
POSIX conformance.
----^----

Another interesting thing is that this requirement was moved from the
XSI extension to the POSIX Base (along with dlsym() itself).


I was curious which way you chose for [3]. The one above follows the
example of SUSv2, clashes with SUSv3 (whose dlsym() rationale and
example are inconsistent anyway, in my view), and it is explicitly
permitted by SUSv4.

I'm obviously unqualified to advise you, but under SUSv4 (ie. a modern
GNU/Linux, even though it's probably not certified), you could make [1]
and [4] more elegant by making the "real" struct member a (void **), and
the "f" auto variable a (void *).

Thanks,
lacos

==============================================================================
TOPIC: Motivation of software professionals
http://groups.google.com/group/comp.lang.c/t/21a3fdec4dd53e6a?hl=en
==============================================================================

== 1 of 10 ==
Date: Sat, Feb 13 2010 2:00 pm
From: Lew


Mike Schilling wrote:
> Lew wrote:
>> There should be a much wider gap between the pay scale of the good
>> developer and that of the putz or newbie.
> ----
>
> I do not think that words means what you think it means.

???

It means precisely what I think it means, going by the first two definitions in
<http://www.urbandictionary.com/define.php?term=putz>

What do /you/ think it means?

--
Lew


== 2 of 10 ==
Date: Sat, Feb 13 2010 2:04 pm
From: "Mike Schilling"


Lew wrote:
> Mike Schilling wrote:
>> Lew wrote:
>>> There should be a much wider gap between the pay scale of the good
>>> developer and that of the putz or newbie.
>> ----
>>
>> I do not think that words means what you think it means.
>
> ???
>
> It means precisely what I think it means, going by the first two
> definitions in <http://www.urbandictionary.com/define.php?term=putz>
>
> What do /you/ think it means?

The first definition :
Literally, vulgar slang for penis, not to be used lightly. More
offensive than the schmuck, which can be used affectionately
or teasingly [1]

In other words, the closest English term is "prick", though "asshole" is
close. Is that what you meant?

1. (Leo Rosten wrote that many years ago, but nowadays you can summarize it
as "W is a schmuck, but Cheney is a putz".)


== 3 of 10 ==
Date: Sat, Feb 13 2010 2:27 pm
From: Lew


Lew wrote:
>>>> There should be a much wider gap between the pay scale of the good
>>>> developer and that of the putz or newbie.

Mike Schilling wrote:
>>> I do not think that words means what you think it means.

Lew wrote:
>> ???
>>
>> It means precisely what I think it means, going by the first two
>> definitions in <http://www.urbandictionary.com/define.php?term=putz>
>>
>> What do /you/ think it means?

Mike Schilling wrote:
> The first definition :
> Literally, vulgar slang for penis, not to be used lightly. More
> offensive than the schmuck, which can be used affectionately
> or teasingly [1]
>
> In other words, the closest English term is "prick", though "asshole" is
> close. Is that what you meant?

That is certainly within the universe of connotations that I intend. However,
definition #2 is the denotative meaning I intend.

> (n) a stupid, ignorant person;
> someone who doesn't pay attention to anything going on;
> one who makes stupid remarks

Meanings 5 and 6 also apply.

What, with a name like "Bloch" I wouldn't know what I'm saying?

Both meanings apply. I have encountered both assholes and idiots in software
development positions, neither of which category are often outed for their
effective incompetence. I used term "putz" to distinguish supposedly
experienced software developers who have no excuse for what is clearly
deliberate malfeasance from those still new to the trade who have a commitment
to good quality. We need to eliminate those ripoff artists in software
development who prey upon management's general ignorance of best practices and
what constitutes quality, who damage projects, who steal jobs from me and from
other competent practitioners (no lie - it's happened to me more than once),
and who generally sustain their poseur status through a combination of
ass-kissing and bullshit, not to say nepotism.

These putzes know full well that they are incompetent. They retaliate against
attempted exposure with a combination of bluster, counter-accusation, sneaky
politics, missing important meetings and other tactics designed to disguise
their nefarious misdeeds. I once exposed such a charlatan, "Steve", to my
employers by writing in two days, from scratch, in about 150 lines of C code
(braces all alone on their own lines, btw), a module that he had spent about
nine months supposedly developing without ever delivering working code, at a
cost to my bosses of nearly a million dollars. When the development team
tried to get "Steve" to change his approach, he got surly and just kept
saying, "My code is fine!" over and over again.

Steve was a putz. He also made a lot more money off that company than I ever
did. Not only should he have made far, far less than I did there, he should
have been arrested.

--
Lew


== 4 of 10 ==
Date: Sat, Feb 13 2010 2:52 pm
From: Joe Wright


Lew wrote:
> Arved Sandstrom wrote:
>> Let's take it as a given that free software has a decent model. I've
>> been, and still am, a participant in the process of creating free
>> software, and I wouldn't do that if it wasn't a good model. However,
>> the main problem with it is that it engages only a small fraction of
>> all software developers, and accounts for only a very small fraction
>> of all software that is written.
>
> Only a small fraction of software developers (and I've known for a long
> time you were in that group) are good enough to write good software,
> free or otherwise.
>
> Most of us do need to get paid, and few of us can make more money than
> as software developers or related jobs. That gives those who are good
> developers little time to spare for writing free software.
>
>> But the real problem, which is not addressed by free software, and
>> which comprises the huge majority of all software, is custom stuff.
>> And it is this category that suffers, and suffers badly, from the lack
>> of professionalism in our field. It is this category where clients
>> would benefit from having proven, guaranteed quantities when it comes
>> to employees/contractors and products.
>
> There should be a much wider gap between the pay scale of the good
> developer and that of the putz or newbie. Something akin to the gap
> between top actors and those who have to wait tables, or top pro
> athletes and those in the minor leagues.
>
Linus Torvalds writes free software. He is handsomely compensated. I
understand that Richard Stallman is not destitute either. Hmmm.

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


== 5 of 10 ==
Date: Sat, Feb 13 2010 2:58 pm
From: "Mike Schilling"


Lew wrote:
> Lew wrote:
>>>>> There should be a much wider gap between the pay scale of the good
>>>>> developer and that of the putz or newbie.
>
> Mike Schilling wrote:
>>>> I do not think that words means what you think it means.
>
> Lew wrote:
>>> ???
>>>
>>> It means precisely what I think it means, going by the first two
>>> definitions in <http://www.urbandictionary.com/define.php?term=putz>
>>>
>>> What do /you/ think it means?
>
> Mike Schilling wrote:
>> The first definition :
>> Literally, vulgar slang for penis, not to be used lightly. More
>> offensive than the schmuck, which can be used affectionately
>> or teasingly [1]
>>
>> In other words, the closest English term is "prick", though
>> "asshole" is close. Is that what you meant?
>
> That is certainly within the universe of connotations that I intend.
> However, definition #2 is the denotative meaning I intend.
>
>> (n) a stupid, ignorant person;
>> someone who doesn't pay attention to anything going on;
>> one who makes stupid remarks

That's where I'd say schmuck instead of putz, but there's unfortunately no
YLS to referee that dispute.


== 6 of 10 ==
Date: Sat, Feb 13 2010 3:31 pm
From: Lew


>>> (n) a stupid, ignorant person;
>>> someone who doesn't pay attention to anything going on;
>>> one who makes stupid remarks

Mike Schilling wrote:
> That's where I'd say schmuck instead of putz,
> but there's unfortunately no
> YLS to referee that dispute.

Understand that Yiddish has spread into the American idiom, and many words
have grown beyond their historic usages.

--
Lew


== 7 of 10 ==
Date: Sat, Feb 13 2010 3:37 pm
From: "Mike Schilling"


Lew wrote:
>>>> (n) a stupid, ignorant person;
>>>> someone who doesn't pay attention to anything going on;
>>>> one who makes stupid remarks
>
> Mike Schilling wrote:
>> That's where I'd say schmuck instead of putz,
>> but there's unfortunately no
>> YLS to referee that dispute.
>
> Understand that Yiddish has spread into the American idiom, and many
> words have grown beyond their historic usages.

Sure, Americans have goyisher kopfs.


== 8 of 10 ==
Date: Sat, Feb 13 2010 3:44 pm
From: Lew


Lew wrote:
>> There should be a much wider gap between the pay scale of the good
>> developer and that of the putz or newbie. Something akin to the gap
>> between top actors and those who have to wait tables, or top pro
>> athletes and those in the minor leagues.

Joe Wright wrote:
> Linus Torvalds writes free software. He is handsomely compensated. I
> understand that Richard Stallman is not destitute either. Hmmm.

How handsomely? How far from destitute?

How does their compensation compare to, say, Drew Brees's? Or Sean Payton's?

What is the ratio between their compensation and that of someone starting out
as a developer? How does it compare to the ratio between Peyton Manning's (of
the Indianopolis Colts) compensation and Brenan Jackson's (of the Pittsburgh
Colts)?

I am espousing pay gaps akin to those of actors or pro athletes.

--
Lew


== 9 of 10 ==
Date: Sat, Feb 13 2010 3:51 pm
From: Lew


Lew wrote:
>>> There should be a much wider gap between the pay scale of the good
>>> developer and that of the putz or newbie. Something akin to the gap
>>> between top actors and those who have to wait tables, or top pro
>>> athletes and those in the minor leagues.

Joe Wright wrote:
>> Linus Torvalds writes free software. He is handsomely compensated. I
>> understand that Richard Stallman is not destitute either. Hmmm.

The fact that they write free software is immaterial to my point.

--
Lew


== 10 of 10 ==
Date: Sat, Feb 13 2010 4:23 pm
From: Öö Tiib


On Feb 13, 5:09 pm, Lew <l...@lewscanon.com> wrote:
> James Kanze wrote:
> > Logically, I think that most of the techniques necessary for
> > making really high quality software would be difficult to apply
> > in the context of a free development.  And at least up to a
>
> Nonsense.  Free software has a much higher rate of adoption of best
> practices for high quality than for-pay software does.
>
> You say so, too.  It's the "logically" with which I take issue.  That
> free software uses the best techniques and has the highest quality in
> the marketplace is entirely logical, in addition to being an observed
> fact.  You just have to avoid false assumptions and fallacies in reasoning.

Not sure what you mean. There are no such logical binary connection.
Opposite is as easy to observe.

Just download few C++ code-bases at random from places like
sourceforge.net and review them. One produced by using good techniques
is really hard to find there. Most code there has quality so low that
it would be unthinkable in professional software house to pass QA peer
review with it. It is easy to logically explain since most of it is
hobby of non-professionals who find software development amusing or
professionals of other language who learn C++ as hobby.

Results are slightly better with larger and more popular open source
products but that is often thanks to huge tester and developer base
and not good techniques used.

In best shape are open source projects that are popular and where
commercial companies are actively participating since they need these
for building or supporting their commercial products. Again it is easy
to see how the companies are actually enforcing the techniques and
quality there and it is likely that the companies use even higher
standards in-house.

Worst what i have seen is the code written by in-house software
department of some smaller non-software companies but that is again
easy to explain by workers of that department obfuscating their work
to gain job security.

So all things have logical explanations and there are no silly binary
connections like free = quality and commercial = lack of quality.

==============================================================================
TOPIC: void * arithmetic
http://groups.google.com/group/comp.lang.c/t/a33b3b6b3dba34c8?hl=en
==============================================================================

== 1 of 3 ==
Date: Sat, Feb 13 2010 2:04 pm
From: Balban


On Feb 12, 3:38 pm, Seebs <usenet-nos...@seebs.net> wrote:
> On 2010-02-12, Balban <bilgehan.bal...@gmail.com> wrote:
> This produces 0x100000, as you appeared to expect.  I can't see any reason
> for it to yield other values, but so far as I can tell, it's equivalent to
> what you described above.
>

It might be that it is a compiler bug then. It is a cross-compiler and
I suspect the generated assembler is not correct.

> Don't use "unsigned long" -- there are real targets on which unsigned long
> is smaller than a pointer.
>

This is going into off-topic areas but as far as I know at least in 32
and 64-bit machines unsigned long always gives the machine's
addressing size whereas unsigned int would give you the machine word
i.e. register size.

But you do have a point in that char * is fairly safe for pointer
arithmetic.

Thanks,

Bahadir


== 2 of 3 ==
Date: Sat, Feb 13 2010 2:20 pm
From: Seebs


On 2010-02-13, Balban <bilgehan.balban@gmail.com> wrote:
> This is going into off-topic areas but as far as I know at least in 32
> and 64-bit machines unsigned long always gives the machine's
> addressing size whereas unsigned int would give you the machine word
> i.e. register size.

Not always. There have been machines on which long was 32-bit and pointer
was 64-bit. Not many, perhaps, and it's arguably a pretty bad choice of
sizes, but it's been done -- that's a big part of why we have "long long".

> But you do have a point in that char * is fairly safe for pointer
> arithmetic.

And, if you really are seeing a compiler bug, this may also work around
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!


== 3 of 3 ==
Date: Sat, Feb 13 2010 3:39 pm
From: Barry Schwarz


On Sat, 13 Feb 2010 14:04:06 -0800 (PST), Balban
<bilgehan.balban@gmail.com> wrote:

>On Feb 12, 3:38 pm, Seebs <usenet-nos...@seebs.net> wrote:
>> On 2010-02-12, Balban <bilgehan.bal...@gmail.com> wrote:
>> This produces 0x100000, as you appeared to expect.  I can't see any reason
>> for it to yield other values, but so far as I can tell, it's equivalent to
>> what you described above.
>>
>
>It might be that it is a compiler bug then. It is a cross-compiler and
>I suspect the generated assembler is not correct.
>
>> Don't use "unsigned long" -- there are real targets on which unsigned long
>> is smaller than a pointer.
>>
>
>This is going into off-topic areas but as far as I know at least in 32
>and 64-bit machines unsigned long always gives the machine's
>addressing size whereas unsigned int would give you the machine word
>i.e. register size.

There are many shades of gray. On IBM z-Architecture machines, a word
is 32 bits while the hardware registers are 64 bits. Furthermore,
unsigned long is 64 bits whether the addressing mode (which is under
program control) is 64 or 32 bits. (There is also a 24 bit
addressing mode for backward compatibility and unsigned long is still
64 bits.)

--
Remove del for email

==============================================================================
TOPIC: Efficency and the standard library
http://groups.google.com/group/comp.lang.c/t/ad9fea19f2f7dd61?hl=en
==============================================================================

== 1 of 5 ==
Date: Sat, Feb 13 2010 3:03 pm
From: Phil Carmody


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:
>>>>> Simpler, and slightly more informative to the caller:
>>>>> 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,
pretty please?

Phil, who uses strlen().
--
Any true emperor never needs to wear clothes. -- Devany on r.a.s.f1


== 2 of 5 ==
Date: Sat, Feb 13 2010 3:05 pm
From: cri@tiac.net (Richard Harter)


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.

(5) The comments are inadequate. The existing comments read
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.


== 3 of 5 ==
Date: Sat, Feb 13 2010 3:23 pm
From: "Chris M. Thomasson"


"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
something like this instead:
_____________________________________________________
size_t
xstrlen(char const* string)
{
char const* end = string;
while (*end) ++end;
return end - string;
}
_____________________________________________________


?

== 4 of 5 ==
Date: Sat, Feb 13 2010 3:35 pm
From: Seebs


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!


== 5 of 5 ==
Date: Sat, Feb 13 2010 5:10 pm
From: "bartc"

"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


==============================================================================
TOPIC: A bit resistant to disruption
http://groups.google.com/group/comp.lang.c/t/a5ddb7c1aa07c7e5?hl=en
==============================================================================

== 1 of 1 ==
Date: Sat, Feb 13 2010 4:16 pm
From: Thad Smith


Thad Smith wrote:
> Francois Grieu wrote:
>> /*
>> Disclaimer: This is a hard problem, only minimally disguised into
>> something on-topic for comp.lang.c
>
> comp.programming and comp.arch.embedded added to the list.
>
>> You are programming a C99 conforming freestanding implementation.
>> Disruption (reset or power off/on cycle) can occur at *ANY* time
>> without advance warning, and stops whatever operation is underway. The
>> program is re-executed from main() after a disruption.
>>
>> The objective is to implement a single bit resistant to disruption,
>> accessed using two procedures to be written:
>> int bRead(void); // Return 0 or 1 according to bit state.
>> void bToggle(void); // Change the state of the bit.
>>
>> These two properties shall be met:
>> a) The bit is stable in the absence of Toggle. That is, the result
>> given by any two undisrupted bRead() is the same unless bToggle() was
>> invoked in-between.
>> b) The bit is changed by Toggle. That is, the result given by any two
>> undisrupted bRead() is different if bToggle() was invoked exactly once
>> in-between and no disruption occurred during that execution of bToggle().
> ....
>> An EEPROM cell can be left neither erased nor programmed by a disrupted
>> eErase unless that cell was already erased, or by a disrupted eProgram.
>> For a cell in such halfway state, eRead returns a value specified only
>> to be 0 or 1. That otherwise unspecified value may in particular change
>> after disruption (due e.g. to uncontrollable random noise and/or
>> temperature and/or voltage drift in the hardware used by eRead), even
>> though the sate of cells is unchanged by disruption or/and eRead.
>>
>> Note: if a cell is not erased (left in a halfway state or programmed),
>> an eProgram of that cell is prohibited. A workaround is to use the
>
> First, this is an uninteresting problem because if a power failure
> occurs during a toggle attempt, the restored state gives no information
> at all.

I'm taking another stab at the problem, based on more analysis and an
understanding of possible use. Thanks to Daniel Giaimo for finding a problem in
the earlier proposal.

Let's assume the variable has three state categories: s1, s2, and t. s1 and s2
are stable states (will not change spontaneously). Other values are transition
values. If the variable is read in a state t, the variable is then changed to
s1 or s2.

This can be used to perform a consistent database state update:
Assume initially database copy A is consistent and dbstate=s1 (database A is
valid). To update, make an updated copy B. At this point both A and B are
consistent. Set dbstate=s2 (database B is valid). Move B to A. Set dbstate=s1.

If power is lost while dbstate is being changed, both database copies are valid,
so restoring the state to either stable state results in a consistent database.
We just need to make sure that s1 and s2 are always stable when an
modification is in progress on copy A or B.

In the following list of sequential states, each of the four bits are
independently erasable and writable (normally implemented in separate bytes).

Bit
dbstate dcba Stable bits
s1 0001 ca
t1a 0011 da
t1b 0111 db
t1c 0110 db
s2 0010 ba
t2a 1010 cb
t2b 1011 dc
t2c 1001 ca
(s1) 0001 ca

To go from state s1 to s2 or s2 to s1, we first re-erase the last bit erased,
then sequentially write the variable to the following transition and stable
states, changing a single bit at a time.

When reading dbstate, if value is s1 or s2, return the value.
If value is txa or txb, erase and rewrite the last bit set, then precede to the
next stable state. If value is txc, re-erase the last bit erased, then precede
to the next stable state.

If power fails when in a transition state, a reading of the state with the above
rules will restore dbstate to a stable value. Multiple interrupts during a
restoration can cause the state values to go from t1b to t1a to s1, but it
doesn't revert any further (similar for t2b to t2a to s2).

Assume power fails during the t1c-s2 or t2c-s1 transition such that the powerup
state reads s2 or s1 with a partially erased bit (d for s1, c for s2). If the
partially erased bit is read as zero, dbstate will be considered stable, even
though there is an unstable bit. The state may revert to the previous
transition state, which, when read, will be advanced to the same stable state.
Assume d is a weak zero in s1 when dbstate starts to advance. The first
operation on advance is to re-erase d, eliminating the weak state, then start
transition to s2.

--
Thad


==============================================================================

You received this message because you are subscribed to the Google Groups "comp.lang.c"
group.

To post to this group, visit http://groups.google.com/group/comp.lang.c?hl=en

To unsubscribe from this group, send email to comp.lang.c+unsubscribe@googlegroups.com

To change the way you get mail from this group, visit:
http://groups.google.com/group/comp.lang.c/subscribe?hl=en

To report abuse, send email explaining the problem to abuse@googlegroups.com

==============================================================================
Google Groups: http://groups.google.com/?hl=en

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home


Real Estate