Thursday, January 7, 2010

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

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

comp.lang.c@googlegroups.com

Today's topics:

* Advanced data structures - 10 messages, 9 authors
http://groups.google.com/group/comp.lang.c/t/2edd7d58412b2f69?hl=en
* A question about netiquette and topicality (on-topic for this group) - 1
messages, 1 author
http://groups.google.com/group/comp.lang.c/t/8cca41167ad2c4fb?hl=en
* a CPAN for C - 3 messages, 2 authors
http://groups.google.com/group/comp.lang.c/t/6d957d79a1c23dac?hl=en
* Statechart - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c/t/146f9d1f43f142f5?hl=en
* x86 binary runs; x86_64 binary throws segfault - 7 messages, 4 authors
http://groups.google.com/group/comp.lang.c/t/9a05cd2f9b5971e8?hl=en
* plauged by seg faults - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c/t/41d11dcef1fcc338?hl=en
* Comparision of C Sharp and C performance - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c/t/4cf78a2afa73b77a?hl=en
* assert in C - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c/t/921be6a4718cfb1b?hl=en

==============================================================================
TOPIC: Advanced data structures
http://groups.google.com/group/comp.lang.c/t/2edd7d58412b2f69?hl=en
==============================================================================

== 1 of 10 ==
Date: Thurs, Jan 7 2010 6:18 am
From: Ben Bacarisse


superpollo <utente@esempio.net> writes:

> Stefan Ram ha scritto:
>> Rui Maciel <rui.maciel@gmail.com> writes:
>>> and unencumbered by those long, tedious series of sanity tests,
>>> which are pretty
>>
>> Taking the possibility of a 0 result of malloc into account
>> is not what I deem to be a »sanity« test ...
>
> excuseme if the question is trivial ... suppose we are in a hosted
> environment with virtual memory management by the os. is it true that
> malloc *never* returns NULL?

No. malloc can return NULL even is such cases. Some systems don't do
this by default, but even then the behaviour can often be changed by
mechanisms outside of your C implementation.

--
Ben.


== 2 of 10 ==
Date: Thurs, Jan 7 2010 6:23 am
From: lacos@ludens.elte.hu


In article <malloc-20100107142912@ram.dialup.fu-berlin.de>, ram@zedat.fu-berlin.de (Stefan Ram) writes:
> superpollo <utente@esempio.net> writes:
>>excuseme if the question is trivial ... suppose we are in a hosted
>>environment with virtual memory management by the os. is it true that
>>malloc *never* returns NULL?
>
> I don't know - maybe someone else can answer this question?
>
> (All I know is that according to ISO/IEC 9899:1999 (E) 7.20.3.3p3
> malloc might return a null pointer.)

malloc() does return a null pointer on GNU/Linux.

http://groups.google.com/group/comp.lang.c/msg/b6b1aff01a34738d?dmode=source

(Message-ID: <wzGFrnpa6nP$@ludens>)

Cheers,
lacos


== 3 of 10 ==
Date: Thurs, Jan 7 2010 7:16 am
From: gwowen


On Jan 7, 2:13 pm, r...@zedat.fu-berlin.de (Stefan Ram) wrote:
>   In C, memory management is an integral part of the algorithm,

So you say. I don't think its part of the algorithm at all, I think
its part of the implementation. I disagree, but I respect that you
differ. However, you have not convinced me. If I want to read about
the complexities of error handling in low memory situations I will buy
"C Error Handling Unleashed". If I want to read about data
structures, and worry about error handling later, I'll buy a book on
data structures. Personally I don't need to be reminded to check
malloc() in didactic examples, unless the thing being taught is error
handling...

Alternatively, if the lack of error handling upsets you so much,
pretend every malloc call is replaced by:

void *xmalloc(size_t sz){
void *ret = malloc(sz);
if(ret) return ret;
fprintf(stderr,"Out of memory"\n");
fflush(NULL);
abort();
}

Any more complicated error handling than that is likely to be so
dependent on application domain and platform that it would not be
relevant to a general purpose algorithm book. I'd be interested to
see you suggest what the error handling should look like in such a
general-purpose book.


== 4 of 10 ==
Date: Thurs, Jan 7 2010 7:33 am
From: ram@zedat.fu-berlin.de (Stefan Ram)


gwowen <gwowen@gmail.com> writes:
>I'd be interested to see you suggest what the error handling
>should look like in such a general-purpose book.

Yes, this question is exactly what the author of such
a book should discuss! In the case of the book given,
he missed to do this.

When implementing data structures in C, the implementation
needs to have a documented policy towards run-time errors.
Authors of such implementations need to be aware of the
different options. This is not beginner's material. This is
hard. Beginner's material is implementing data structures
and ignoring this question.

== 5 of 10 ==
Date: Thurs, Jan 7 2010 8:18 am
From: Eric Sosman


On 1/7/2010 8:25 AM, superpollo wrote:
> Stefan Ram ha scritto:
>> Rui Maciel <rui.maciel@gmail.com> writes:
>>> and unencumbered by those long, tedious series of sanity tests, which
>>> are pretty
>>
>> Taking the possibility of a 0 result of malloc into account
>> is not what I deem to be a »sanity« test ...
>
> excuseme if the question is trivial ... suppose we are in a hosted
> environment with virtual memory management by the os. is it true that
> malloc *never* returns NULL?

A moment's thought will show that every malloc() must
eventually return NULL (or die catastrophically, failing to
conform to its specification). Consider: A non-NULL value
returned by malloc() must be distinct from all other values
it has returned, if those allocated blocks have not been
released. sizeof(void*) is finite, hence void* has only a
finite number of possible distinct values (at least one of
which is equal to NULL). If there are N possible void*
values and you call malloc(1) N times, at least one of those
calls (usually far more than one) must return NULL.

--
Eric Sosman
esosman@ieee-dot-org.invalid


== 6 of 10 ==
Date: Thurs, Jan 7 2010 7:54 am
From: Seebs


On 2010-01-07, superpollo <utente@esempio.net> wrote:
> excuseme if the question is trivial ... suppose we are in a hosted
> environment with virtual memory management by the os. is it true that
> malloc *never* returns NULL?

Probably not.

That said, you could go years of active software development and use without
ever seeing it happen.

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


== 7 of 10 ==
Date: Thurs, Jan 7 2010 8:14 am
From: Rui Maciel


Stefan Ram wrote:

> Rui Maciel <rui.maciel@gmail.com> writes:
>>When an author starts to include each and every validation test in a code
>>snippet example then the example code becomes verbose. As a consequence,
>>the reader's attention will also be on minor and even irrelevant details
>
> Yes, but for C programming memory management is not an
> irrelevant detail.
>
> If the author would have wanted to focus on how to do
> it /without manual memory management/ he could have chosen
> a language with a garbage collector, like Java, or - if it
> had to be C-like - a C-like language with a garbage collector,
> like C with the Boehm collector. But he had chosen to use C.

This is silly. The author provided examples to illustrate concepts. In order
to better communicate concepts it is better to focus on the meaningful details
instead of wasting time with secondary, irrelevant aspects which is safe to
assume that all potential readers are already very familiar with.

Moreover, if an author opts to present concepts through pseudo-code instead of C
code then his work will not be less valuable and even the author would not be
more open to criticism. Therefore, if using purely abstract languages is not a
sin nor a sign of incompetence then why should anyone complain that an author
used a real-world programming language while leaving out irrelevant and
secondary details?


>>and unencumbered by those long, tedious series of sanity tests, which are
>>pretty
>
> Taking the possibility of a 0 result of malloc into account
> is not what I deem to be a »sanity« test ...

Is that even relevant, particularly in this discussion?


>>much irrelevant for the topic being discussed.
>
> ... nor irrelevant for C programing.

I believe you don't quite get it. Let's put it in this way: if a C programmer
picks up a book entitled "Advanced data structures" and he doesn't find a single
validation on calls to malloc(), do you believe that the absence of those tests
will hinder his ability to learn any topic covered in that book? And do you
believe that the problem would also be there if the book's examples were in
pseudo-code instead of C?


> And then the author /does not even discuss/ this problem.

Why should he? That's terribly basic stuff. It's usually covered extensively
right at the beginning of any introductory course. Why should the author waste
time with topics which clearly should be a prerequisite to pick up the book?
Should the author also waste time discussing some intricacies of using the
english language to communicate with the reader?


> It would not have been such a bad book, if he would have first
> explained how to do proper memory management in C and then why
> he will not use this in the rest of the book.

It's impressive how you are quick to label a book as being bad just because the
author chose to leave out such basic stuff, and therefore irrelevant and
meaningless due to the book's topic, out of it.


> But he did not
> mention this. Which gives the impression that he might not even be
> aware of it.

If the author doesn't mention computers will that give you the impression that
he might not even be aware they exist?


> I agree that the author of "Advance Data Structures" should
> have read a book on basic C programming.

It appears that you are far too keen to quickly accuse someone as being
incompetent.


Rui Maciel


== 8 of 10 ==
Date: Thurs, Jan 7 2010 8:36 am
From: Rui Maciel


Stefan Ram wrote:

> gwowen <gwowen@gmail.com> writes:
>>I'd be interested to see you suggest what the error handling
>>should look like in such a general-purpose book.
>
> Yes, this question is exactly what the author of such
> a book should discuss! In the case of the book given,
> he missed to do this.

That's your opinion, which you are free to have and express. Yet, it doesn't
make it right, let alone an absolute truth.


> When implementing data structures in C, the implementation
> needs to have a documented policy towards run-time errors.

I believe this is exactly where you fail to understand the issue. The source
code snippets aren't supposed to be real world implementations of those data
structures. They are nothing more than small examples that are used to simply
illustrate the subjects being discussed. They aren't there to be picked up,
transcribed to a text file and slapped into a project tree. If the author had
intended to do that then he wouldn't have wasted his time writing a book. He
would've been writing libraries for his data structures.

On the other hand, if you intend to write a book covering an advanced subject
then what you will do is provide small examples in the form of code snippets in
order to better illustrate the subjects you have been discussing. Those code
snippets will be straight to the point and you will omit irrelevant, secondary
details in order to efficiently convey your ideas. And that's what has been
done.


> Authors of such implementations need to be aware of the
> different options.

What leads you to believe they aren't?


> This is not beginner's material.

...which makes it safe to assume that the author doesn't need to waste his time
covering beginner's subjects, such as validating calls to malloc().


> This is
> hard. Beginner's material is implementing data structures
> and ignoring this question.

...which only happens if the reader doesn't know how to code in C to begin with
and therefore should be reading an introductory C book before picking up books
targeted at a more knowledgeable readership.


Rui Maciel


== 9 of 10 ==
Date: Thurs, Jan 7 2010 9:03 am
From: Keith Thompson


jacob navia <jacob@spamsink.net> writes:
> Stefan Ram a écrit :
>> Rui Maciel <rui.maciel@gmail.com> writes:
>>> When an author starts to include each and every validation test in
>>> a code snippet example then the example code becomes verbose. As a
>>> consequence, the reader's attention will also be on minor and even
>>> irrelevant details
>>
>> Yes, but for C programming memory management is not an
>> irrelevant detail.
>>
>
> Yes it is. If malloc fails, the program crashes. So what?
>
> That's a correct behavior for a sample program!
[...]

How do you know it crashes?

The glibc implementation of printf's "%s" format prints the string
"(null)" given a null pointer. I've seen people here advocate
"friendly" handling of null pointers for other functions as well,
such as treating a null pointer as equivalent to a pointer to an
empty string. Misusing a null pointer gives you undefined behavior.
A crash is the most common behavior, but not the only possibility.

I can understand leaving out checking in a sample program, but
there needs to be some mention of the need for it in the real world.
(I'm not even sure what book we're talking about; I'm just making
a general point.)

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


== 10 of 10 ==
Date: Thurs, Jan 7 2010 10:32 am
From: Kaz Kylheku


On 2010-01-07, superpollo <utente@esempio.net> wrote:
> Stefan Ram ha scritto:
>> Rui Maciel <rui.maciel@gmail.com> writes:
>>> and unencumbered by those long, tedious series of sanity tests, which are pretty
>>
>> Taking the possibility of a 0 result of malloc into account
>> is not what I deem to be a »sanity« test ...
>
> excuseme if the question is trivial ... suppose we are in a hosted
> environment with virtual memory management by the os. is it true that
> malloc *never* returns NULL?

What do you conclude from the following observations?

1. malloc returns a fixed-size pointer with a finite number of bits
in its representation, giving rise to an upper bound on the number
of unique values it can hold.

The number of bits in void * is CHAR_BIT * sizeof(void *).
Not all of these may be value-contributing,b ut that is the upper
bound on the number of value-contributing bits. (We just care
about the existence of an upper bound, not what it is).

An upper bound on the number of bits means an upper bound on the
number of distinct values, which is given by pow(2, bits).

Thus the void * pointer type can only represent so many distinct
values.

2. malloc returns either null, or a unique address: a new object
that is different from any other live object in the program.

In light of 1 and 2, can malloc keep producing objects indefinitely?

==============================================================================
TOPIC: A question about netiquette and topicality (on-topic for this group)
http://groups.google.com/group/comp.lang.c/t/8cca41167ad2c4fb?hl=en
==============================================================================

== 1 of 1 ==
Date: Thurs, Jan 7 2010 6:42 am
From: Tom St Denis


On Jan 7, 9:05 am, gaze...@shell.xmission.com (Kenny McCormack) wrote:
> In article <Tf-dnS5tGJ90T9jWnZ2dnUVZ8tti4...@brightview.co.uk>,
> Tim Streater  <timstrea...@waitrose.com> wrote:
>
>
>
> >On 07/01/2010 02:20, Kenny McCormack wrote:
> >> A common scenario on Usenet is that someone will post an item to a
> >> bunch of groups (this is referred to as "crossposting"), some of which
> >> are "on-topic" and others are not (by whatever definition is in effect
> >> in each affected group).  What often happens is that posters from groups
> >> who deem it to be "off topic" will post, to all affected groups, that it
> >> is "off topic".  But, of course, the problem with this is that they are
> >> posting this message of off-topicness to groups in which the posting
> >> *is* on-topic.  This then leads to recriminations from those groups
> >> where it is "on-topic" and of course re-recriminations/re-re-recrimination,
> >> etc, etc.
>
> >> What do people think?  Should the bearers of the off-topicness just STFU
> >> about it, or do they have a right to make their views known?
>
> >Only in the group(s) where they think it's off-topic, I'd have thought.
>
> A sensible position.  However, in practice:
>     1) People never do it.  Basically, it is the limit of most people's
>         ability to do a "reply all".  This is a technical limitation,
>         not a social limitation.  However, see next.
>     2) I think that some people think it is their mission in life to
>         tell everyone that such and such is OT in "my newsgroup".
>         I.e., an offense has been committed and it is their duty to tell
>         one and all.

You're right in that some people get off in being the net-cop. Just
like some people get off on trolling USENET.

...

just saying...

Tom

==============================================================================
TOPIC: a CPAN for C
http://groups.google.com/group/comp.lang.c/t/6d957d79a1c23dac?hl=en
==============================================================================

== 1 of 3 ==
Date: Thurs, Jan 7 2010 6:49 am
From: Tom St Denis


On Jan 6, 1:21 am, jacob navia <ja...@spamsink.net> wrote:
> I am trying to design and implement a standard container library
> for C.
>
> I report about it regularly in this newsgroup.

Write the library for C90 and release it under LGPL and maybe I might
care about it.

If the library requires lcc-win32 extensions and is proprietary you
can keep it.

Tom


== 2 of 3 ==
Date: Thurs, Jan 7 2010 9:19 am
From: Marco


On Jan 7, 7:49 am, Tom St Denis <t...@iahu.ca> wrote:
> On Jan 6, 1:21 am, jacob navia <ja...@spamsink.net> wrote:
>
> > I am trying to design and implement a standard container library
> > for C.
>
> > I report about it regularly in this newsgroup.
>
> Write the library for C90 and release it under LGPL and maybe I might
> care about it.
>
> If the library requires lcc-win32 extensions and is proprietary you
> can keep it.
>
> Tom

Totally agree - if not written in standard C (unfortunately that still
means C90 today) then most folks just won't want it


== 3 of 3 ==
Date: Thurs, Jan 7 2010 9:25 am
From: Tom St Denis


On Jan 7, 12:19 pm, Marco <prenom_no...@yahoo.com> wrote:
> Totally agree - if not written in standard C (unfortunately that still
> means C90 today) then most folks just won't want it

Nothing wrong with C90. Only thing I borrow from C99 is long long. I
think that VLA and mid-block declarations are bad coding practice.
I'd settle for his library being C99 though.

My suggestion that it be C90 was because I suspect it's being written
for his compiler which isn't 100% ISO compatible.

Tom

==============================================================================
TOPIC: Statechart
http://groups.google.com/group/comp.lang.c/t/146f9d1f43f142f5?hl=en
==============================================================================

== 1 of 1 ==
Date: Thurs, Jan 7 2010 7:56 am
From: "Remo D."


On Jan 7, 1:59 pm, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:

> This is a big win when the process is documented as a state machine
> but it can be a problem to unravel what a state machine is really
> doing if the process is either not documented or is described by some
> other means.  I mention this just as a cautionary note: state machines
> can be clear for the author but hard to decode for the reader!

I agree, follow the logic of an undocumented FSM could be a nightmare!

My point is just that other methods to encode a state machine in a C
program (e.g. via a table of pointers to functions or using while()
and state variables) just make the task harder, while using goto (in a
disciplined form as the macro above) preserve the state machine
structure.

This method is intended to be refined and adapted to the specific
case. For example, the STATE() macro could read a symbol from a
default input stream and handle the EOF condition.


#define STATE(x) s_##x : if ((c=fgetc(f)) == EOF) goto s_END;

#define ENDSTATE s_END:


The idea is to hide those details that are implicit in the FSM
structure. Of course you can do horribly wrong things using this
thecniique but this is true for 99.9% of C :)

==============================================================================
TOPIC: x86 binary runs; x86_64 binary throws segfault
http://groups.google.com/group/comp.lang.c/t/9a05cd2f9b5971e8?hl=en
==============================================================================

== 1 of 7 ==
Date: Thurs, Jan 7 2010 8:04 am
From: Don


Hello, folks. I have two boxes, both running Debian GNU/Linux 5,
kernel 2.6.26, and gcc version 4.3.2. One box is an AMD64 (obviously,
the x86_64 architecture), and one is an Intel i686.

I have a very simple program designed to a base string, which is a
numeral in base 12, supplied at the command line or from standard
input, into decimal, then send it back to the calling function as a
double. Very simple, under 200 lines.

Before converting the string to a decimal double, I test whether the
string is written in exponential notation, and if so, send it to a
function to convert it out of exponential notation. This consists of
juggling the integral marker (hard-coded as a semicolon, at this
point) back or forward in the string depending on the value of the
exponent, cutting off the exponent in the process. It was a hairier
problem than I expected, and it's not pretty, but it works *almost*
every time. I know that the problem is in this function because no
errors occur when the string is *not* in exponential notation, and
this function is therefore never called.

It works properly on all tested strings sent from the command line.

When I supply the strings from standard input, however, some strange
things happen. They only happen on the second string sent through the
function. The errors do *not* occur if I send a string that isn't in
exponential notation, which makes me think the problem is in the
exponential-handling function.

If the first two strings sent through stdin are "X44;4" (decimal
1492.3repeating) and "X;444e2" (the same number), the first is
converted properly and the second is converted to 17908.0000, which
about the proper number multiplied by twelve (not quite, but very
close). All subsequent passes work fine, and the same input in any
place but the second time works fine. "X44;4" does *not* fail when
passed through second.

If the first two strings sent through stdin are "X;3" (10.25 decimal)
and "0;x3e1" (the same number), the first is converted properly and
the second throws a segfault. Entering "0;x3e1" in any other place
(as in, not second from standard input) works perfectly fine,
producing "10.25" as output predictably. "X;3" does *not* fail when
passed through second.

I stared at this for some time, then in desperation sshed over to my
i686 box, recompiled the same code, and tried it there. Both of these
situations worked properly, without any issues.

I'm compiling with the following command line:

gcc -lm -o dec dec.c

I've googled the issue; in some places I'm told to try compiling with
the -arch x86_64 flag, and in other places I'm told that gcc should
automatically compile for x86_64 on an x86_64 system. I can't try it
for eight or nine more hours (I'm at work), so I thought I'd ask here
and see if perhaps the code itself is bad.

Here's the function at issue: it takes a pointer to the string to be
converted, plus an integer representing the point of the string where
the "e" is, computed at call time (I loop through the string looking
for an "e" or "E" to determine whether it needs to be called at all;
since I already had the loop index set for that when I called the
function, I thought it made sense to send it to the function rather
than let the function do the same loop again itself). Error checking
for the input has already occurred at this point, but it's proper
input that's causing this problem anyway. It calls "doztodec(char
*s)" to convert the part of the string that represents the exponent to
decimal; this function works fine on all input, and typically returns
a double. I'm putting it in a char because the exponent has to be
below 127 (my precision doesn't get anywhere like that high here), but
I understood that a cast would be done automatically in this case.
Should I make it explicit? I've sprinkled a lot of extra comments for
this posting to make it clearer what's going on.
*******
int expkill (char *s, int expspot)
{
int i,j;
char zensuf[3]; /* the base-12 exponent suffix */
char exp; /* the value of the suffix */
int semi; /* where semicolon is in original string */

for (i = expspot+1,j=0; *(s+i) != '\0'; ++i,++j)
*(zensuf+j) = *(s+i); /* put the exponent in zensuf */
exp = doztodec(zensuf); /* convert the exponent to decimal char */
for (semi=0; *(s+semi) != ';' && *(s+semi) != '\0'; ++semi); /* set
semi = semicolon's location */
*(s+expspot) = '\0'; /* cut off the "e" and the exponent */
if (semi >= strlen(s))
return 0; /* if the semicolon is already at the end of the string,
end processing */
if (exp > 0) { /* if the semicolon needs to be moved to the right */
for (i=semi; *(s+i+1) != '\0'; ++i)
*(s+i) = *(s+i+1); /* move everything over to get rid of original
semicolon */
*(s+i) = '\0'; /* move string terminator to new end of string */
for (i=strlen(s); i > semi+exp; --i)
*(s+i) = *(s+i-1); /* move the rest of string over to make room for
new semi */
*(s+semi+exp) = ';'; /* insert the new semicolon */
} else if (exp < 0) { /* if the semicolon needs to be moved to the
left */
exp = -exp, ++exp;
for (i=strlen(s)+exp; i >= 0; --i)
*(s+i) = *(s+i-exp); /* move string to right to make room for new
digits */
for (i=0; i < exp; ++i)
*(s+i) = '0'; /* pad left side of string with zeroes */
for (semi=0; *(s+semi) != ';'; ++semi); /* find location of
semicolon */
for (i=semi; *(s+i) != '\0'; ++i)
*(s+i) = *(s+i+1); /* move over to eliminate original semicolon */
*(s+i) = '\0'; /* insert new end of string */
*(s+1) = ';'; /* put in new semicolon */
}
if (*(s+strlen(s)-1) == ';')
*(s+strlen(s)-1) = '\0'; /* if there's no fractional part now, don't
have semicolon */
return 0;
}
*******

The contents of the file that produces erroneous input is:
X44;4
X;444e2

The contents of the file that throws a segfault is:
X;3
0;X3e1

Thanks to anyone who can help me figure this out.


== 2 of 7 ==
Date: Thurs, Jan 7 2010 8:37 am
From: Eric Sosman


On 1/7/2010 11:04 AM, Don wrote:
> Hello, folks.[...]

Could you post a short, complete program that demonstrates
the problem? Based on your report that "it works" with strings
entered on the command line but fails when input is read from a
stream, I have a sneaking suspicion that the problem is in the
way the strings are read. (If you're using fgets(), did you
remember that the '\n' at the end of the line is still there?)

Also, a little more information on your duodecimal notation
would be welcome. It seems that 'X' or 'x' stands for the
duodecimal digit ten, and I'm going to guess that 'Y'/'y' mean
eleven -- but that doesn't seem to be spelled out anywhere.

--
Eric Sosman
esosman@ieee-dot-org.invalid


== 3 of 7 ==
Date: Thurs, Jan 7 2010 8:57 am
From: Don


On Jan 7, 11:37 am, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
> On 1/7/2010 11:04 AM, Don wrote:
>
> > Hello, folks.[...]
>
>      Could you post a short, complete program that demonstrates
> the problem?

Hmm. Not for several more hours, at least; I don't have a compiler
here at work, so I couldn't ensure that what I posted would work.
Plus, to get it really working I'd probably have to include all the
code.

I'm not using fgets(), though; I'm using a home-rolled getline(),
because I'm working through K&R and it's comfortably familiar to me.

Yes, 'X' or 'x' would work for ten; also 'T', 't', 'A', or 'a'. I
tend to use 'X' myself. Eleven is 'E', 'B', or 'b' (not 'e', as that
would conflict with the exponents). I didn't think it would be
relevant since whenever this expkill() function is not called,
everything works great; and indeed, whenever expkill() *is* called, it
all works great except for the second item read in.

I'll go ahead and humiliate myself and post the entire code. I
haven't worked in error checking yet, but since it's good input that's
breaking it I don't suppose that matters at this point.

*******
int main(int argc, char *argv[])
{
int c;
char doznum[MAXLINE];

while (*(++argv) != NULL && *argv[0] == '-') {
while (c = *++argv[0])
switch (c) {
default:
fprintf(stderr,"dec: illegal option \"%c\"\n",c);
break;
}
}
if (*(++argv) == NULL) {
printf("%f\n",doztodec(*(argv-1)));
return 0;
}
while (getline(doznum,MAXLINE) != EOF) {
printf("%f\n",doztodec(doznum));
}
return 0;
}

/* convert exponential notation to normal b/f processing */
int expkill (char *s, int expspot)
{
int i,j;
char zensuf[3];
char exp;
int semi; /* where semicolon is */

for (i = expspot+1,j=0; *(s+i) != '\0'; ++i,++j)
*(zensuf+j) = *(s+i);
exp = doztodec(zensuf);
for (semi=0; *(s+semi) != ';' && *(s+semi) != '\0'; ++semi);
*(s+expspot) = '\0';
if (semi >= strlen(s))
return 0;
if (exp > 0) {
for (i=semi; *(s+i+1) != '\0'; ++i)
*(s+i) = *(s+i+1);
*(s+i) = '\0';
for (i=strlen(s); i > semi+exp; --i)
*(s+i) = *(s+i-1);
*(s+semi+exp) = ';';
} else if (exp < 0) {
exp = -exp, ++exp;
for (i=strlen(s)+exp; i >= 0; --i)
*(s+i) = *(s+i-exp);
for (i=0; i < exp; ++i)
*(s+i) = '0';
for (semi=0; *(s+semi) != ';'; ++semi);
for (i=semi; *(s+i) != '\0'; ++i)
*(s+i) = *(s+i+1);
*(s+i) = '\0';
*(s+1) = ';';
}
if (*(s+strlen(s)-1) == ';')
*(s+strlen(s)-1) = '\0';
return 0;
}

double doztodec(char *s)
{
char frac[MAXDIGS];
int i, j;
int endpoint;
double decnum = 0.0;

for (i=0; *(s+i) != '\0'; ++i)
if (*(s+i) == 'e' || *(s+i) == 'E')
expkill(s,i);
for (i=0; *(s+i) != ';'; ++i);
endpoint = i;
if (endpoint < (strlen(s) - 1)) {
for (i=++i,j=0; *(s+i) != '\0'; ++i,++j)
*(frac+j) = *(s+i);
*(s+endpoint) = *(frac+j) = '\0';
decnum += fracdec(frac);
}
decnum += wholedec(s);
return decnum;
}

double wholedec(char *s)
{
int addnum = 0; /* added to decnum each loop */
int i;
int multiple = 1; /* provides multiple for loop */
double decnum = 0.0; /* final result to return */
char sign = 0;

reverse(s);
if (*(s+strlen(s)-1) == '-') {
sign = 1;
*(s+strlen(s)-1) = '\0';
}
for (i=0; *(s+i) != '\0'; ++i) {
addnum = decmify(*(s+i));
addnum *= multiple;
decnum += addnum;
multiple *= 12;
}
return (sign == 0) ? decnum : decnum * -1;
}

double fracdec(char *s)
{
int i;
double divisor = 1.0;
double fracval = 0.0;

for (i=0; *(s+i) != '\0'; ++i)
divisor *= 12.0;
fracval = wholedec(s) / divisor;
return fracval;
}

char decmify(char c)
{
switch (c) {
case '0': return 0; break;
case '1': return 1; break;
case '2': return 2; break;
case '3': return 3; break;
case '4': return 4; break;
case '5': return 5; break;
case '6': return 6; break;
case '7': return 7; break;
case '8': return 8; break;
case '9': return 9; break;
case 'X': case 'x': case 'T': case 't': case 'A': case
'a':
return 10; break;
case 'E': case 'B': case 'b':
return 11; break;
default: return 0; break;
}
}

void reverse(char *s)
{
int i, j;
char tmp;

for (i=0, j=strlen(s)-1; i<j; ++i, --j) {
tmp = *(s+i);
*(s+i) = *(s+j);
*(s+j) = tmp;
}
}

int getline(char *s, int lim)
{
int c, i;

for (i=0; (c=getchar())!=EOF && c!='\n' && c!='\t' && c!=' '; ++i) {
if (i < lim-1)
*(s+i) = c;
else if (i == lim)
*(s+i) = '\0';
}
if (c == EOF)
return EOF;
*(s+i) = '\0';
return i;
}
*******
Input file that returns wrong output:
*******
X44;4
X;444e2
*******
Input file that throws a segfault:
*******
X;3
0;X3e1
*******
These errors only show up on my AMD64 box, not on my x86 box. The
same numbers that throw errors when on the second line of the input
file do not when on any other line.

Thanks again.


== 4 of 7 ==
Date: Thurs, Jan 7 2010 9:00 am
From: Don


Naturally, forgot to post all the pre-main stuff:
*******
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>

#define MAXDIGS 30
#define MAXLINE 30

int getline(char *s, int lim);
void reverse(char *s);
char decmify(char c);
double wholedec(char *s);
double doztodec(char *s);
double fracdec(char *s);
int expkill (char *s, int expspot);
*******
That, plus the rest of it. Thanks again.


== 5 of 7 ==
Date: Thurs, Jan 7 2010 9:18 am
From: James Dow Allen


On Jan 7, 11:57 pm, Don <dgoodman...@gmail.com> wrote:
> I'll go ahead and humiliate myself and post the entire code.

The foolishest question is the unasked one.
Nevertheless I'd suggest, as a later exercise,
trying to simplify this code.

> /* convert exponential notation to normal b/f processing */
> int expkill (char *s, int expspot)
> {
>         int i,j;
>         char zensuf[3];
>         char exp;
>         int semi; /* where semicolon is */
>
>         for (i = expspot+1,j=0; *(s+i) != '\0'; ++i,++j)
>                 *(zensuf+j) = *(s+i);
>         exp = doztodec(zensuf);

I'd not be surprised if your error is right here! The for loop
does NOT copy the '\0' character, but doztodec() depends on
it. Since uninitialized bytes in zensuf[] will vary based
on "irrelevant" details, this would tend to explain
your symptoms.

By the way, when in doubt, use asserts or printf's to check
what's going on. For example a
fprintf(stderr, "Expkill %d %d\n", strlen(s), expspot);
at the beginning of expkill() would error-check its args
(though not the actual problem here).

>         [several more lines snipped]

I didn't study the whole code. I just assumed that, were I
to find the error before patience ran outit would
be at beginning of examined code. :-)

James Dow Allen


== 6 of 7 ==
Date: Thurs, Jan 7 2010 9:35 am
From: Ben Bacarisse


Don <dgoodmaniii@gmail.com> writes:

> On Jan 7, 11:37 am, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
>> On 1/7/2010 11:04 AM, Don wrote:
>>
>> > Hello, folks.[...]
>>
>>      Could you post a short, complete program that demonstrates
>> the problem?
<snip>
> I'll go ahead and humiliate myself and post the entire code. I
> haven't worked in error checking yet, but since it's good input that's
> breaking it I don't suppose that matters at this point.
>
> *******
> int main(int argc, char *argv[])
> {
> int c;
> char doznum[MAXLINE];
>
> while (*(++argv) != NULL && *argv[0] == '-') {
> while (c = *++argv[0])
> switch (c) {
> default:
> fprintf(stderr,"dec: illegal option \"%c\"\n",c);
> break;
> }
> }
> if (*(++argv) == NULL) {
> printf("%f\n",doztodec(*(argv-1)));
> return 0;
> }
> while (getline(doznum,MAXLINE) != EOF) {
> printf("%f\n",doztodec(doznum));
> }
> return 0;
> }
>
> /* convert exponential notation to normal b/f processing */
> int expkill (char *s, int expspot)
> {
> int i,j;
> char zensuf[3];
> char exp;
> int semi; /* where semicolon is */
>
> for (i = expspot+1,j=0; *(s+i) != '\0'; ++i,++j)
> *(zensuf+j) = *(s+i);

The string in zensuf is not null terminated. You stop when "see" the
null but you never put it into the array.

> exp = doztodec(zensuf);

This call expects a proper string -- one the is null terminated.

> for (semi=0; *(s+semi) != ';' && *(s+semi) != '\0'; ++semi);
> *(s+expspot) = '\0';
> if (semi >= strlen(s))
> return 0;
> if (exp > 0) {
> for (i=semi; *(s+i+1) != '\0'; ++i)
> *(s+i) = *(s+i+1);
> *(s+i) = '\0';
> for (i=strlen(s); i > semi+exp; --i)
> *(s+i) = *(s+i-1);
> *(s+semi+exp) = ';';
> } else if (exp < 0) {
> exp = -exp, ++exp;
> for (i=strlen(s)+exp; i >= 0; --i)
> *(s+i) = *(s+i-exp);
> for (i=0; i < exp; ++i)
> *(s+i) = '0';
> for (semi=0; *(s+semi) != ';'; ++semi);
> for (i=semi; *(s+i) != '\0'; ++i)
> *(s+i) = *(s+i+1);
> *(s+i) = '\0';
> *(s+1) = ';';
> }
> if (*(s+strlen(s)-1) == ';')
> *(s+strlen(s)-1) = '\0';
> return 0;
> }
>
> double doztodec(char *s)
> {
> char frac[MAXDIGS];
> int i, j;
> int endpoint;
> double decnum = 0.0;
>
> for (i=0; *(s+i) != '\0'; ++i)

See? There many be no null.

> if (*(s+i) == 'e' || *(s+i) == 'E')
> expkill(s,i);
> for (i=0; *(s+i) != ';'; ++i);
> endpoint = i;
> if (endpoint < (strlen(s) - 1)) {
> for (i=++i,j=0; *(s+i) != '\0'; ++i,++j)
> *(frac+j) = *(s+i);
> *(s+endpoint) = *(frac+j) = '\0';
> decnum += fracdec(frac);
> }
> decnum += wholedec(s);
> return decnum;
> }

This is not magic or quick eyes. I compiled with -g, ran it under
valgrind and followed the logic to see what was wrong. i don't know
how I managed without valgrind! There may be other errors, but deal
with them one at a time.

BTW, a quick tip: Your code will loads easier to read is every *(x+e)
was replaced by x[e]. Most people expect to see pointers indexed with
[] and it is much easier to read.

--
Ben.


== 7 of 7 ==
Date: Thurs, Jan 7 2010 10:36 am
From: Don


On Jan 7, 12:18 pm, James Dow Allen <jdallen2...@yahoo.com> wrote:
> The foolishest question is the unasked one.
> Nevertheless I'd suggest, as a later exercise,
> trying to simplify this code.

Yes! I'm actually fairly happy with most of it, other than the expkill
() mess. But that is definitely beyond ugly. There must be a better
way to do that.

> I'd not be surprised if your error is right here!  The for loop
> does NOT copy the '\0' character, but doztodec() depends on
> it.  Since uninitialized bytes in zensuf[] will vary based
> on "irrelevant" details, this would tend to explain
> your symptoms.

Hmm. Yes, I'll fix that; funny I missed it, when generally I end up
putting '\0's where they already are just to be sure. But would that
really explain why it fails consistently on the second call, and only
the second call, on x86_64 and not on i686?

@Ben Bacarisse:

I'd never heard of valgrind before today; I'll be sure to look at it.
I just recently discovered Beej's Quick Guide to GDB, which looks like
it'll help me a lot, too.

> BTW, a quick tip: Your code will loads easier to read is every *(x+e)
> was replaced by x[e]. Most people expect to see pointers indexed with
> [] and it is much easier to read.

Hmm. When I went through the pointers chapter in K&R, it advised me
to go through my old programs with the array indexing and change them
to pointers, as it would be faster that way, though harder to read "at
least for the uninitiated."

Because you are clearly initiated, I question this now. Is array
indexing more normal? That would be annoying for me, since I've
finally gotten into the habit of using the pointer notation, but I'd
rather the code be maintainable.

==============================================================================
TOPIC: plauged by seg faults
http://groups.google.com/group/comp.lang.c/t/41d11dcef1fcc338?hl=en
==============================================================================

== 1 of 1 ==
Date: Thurs, Jan 7 2010 8:30 am
From: cerr


On Jan 7, 12:47 am, Michael Foukarakis <electricde...@gmail.com>
wrote:
> On Jan 6, 12:30 am, cerr <ron.egg...@gmail.com> wrote:
>
>
>
>
>
> > On Jan 5, 1:23 pm, David Resnick <lndresn...@gmail.com> wrote:
>
> > > On Jan 5, 2:40 pm, cerr <ron.egg...@gmail.com> wrote:
>
> > > > Hi There,
>
> > > > My daemon app keeps terminating and i'm trying to figure out why and
> > > > where. I have a good idea tho. I'm using a push - pop FIFO system for
> > > > log messages. I have a syslog message after the push and after the pop
> > > > function and see both appearingh all the time and hence i think that
> > > > both, push() and pop() works fine. However, the messages get popped
> > > > off in a thread from where i send the data off. I'm using following
> > > > code:
>
> > > > pthread_mutex_lock(&log_mtx);
> > > >       Qstr=pop(&msglist, &locLen);
> > > >       syslog(LOG_ERR, "DUBUG: popped succesfully!");
> > > >       strncpy(res,Qstr,LOG_BUF_SIZE);
> > > >       res[LOG_BUF_SIZE]='\0';
> > > >       strcat(res,"\n");
> > > >       pthread_mutex_unlock(&log_mtx);
> > > >       if (log_sock>-1) {
> > > >         sndlen=strlen(res);
> > > >         reclen=send(log_sock, res, sndlen, 0);
> > > >         if (reclen != sndlen) {
> > > >           if (reclen==-1){
> > > >             syslog(LOG_ERR, "nlog: send failed...,errno: %s!", strerror
> > > > ( errno ));
> > > >           }
> > > >           syslog(LOG_ERR, "nlog: \"%s\" not sent, strlen(%d) - sent %d",res,
> > > > sndlen, reclen);
> > > >         }
> > > >         else {
> > > >           syslog(LOG_ERR, "DEBUG: sent okay, receive ack");
>
> > > > The last message I see in syslog before my app crashes is "DUBUG:
> > > > popped succesfully!"
> > > > Now the declaration of those variables are as follows:
> > > >   char res[LOG_BUF_SIZE+2]={0};
> > > >   char *Qstr;
> > > >   int locLen;
> > > >   int sndlen;
> > > > while msglist is from type char** and QLen from type int and declared
> > > > globally.
> > > > LOG_BUF_SIZE is a define and set to 512.
>
> > > > Does anyone have a clue where my app is terminating and or should i be
> > > > looking somewhere else all together? The system worked fine before i
> > > > implemented this new FIFO system...
> > > > Thanks for hints and suggestions!
> > > > Ron
>
> > > I'd check the return value of pop.  Is it a reasonable pointer?  NULL?
>
> > Yep as Beej had suggested, I included a check for NULL:
> >       if (Qstr!=NULL)
> >         syslog(LOG_ERR, "DUBUG: popped succesfully!");
> >       else {
> >         syslog(LOG_ERR, "DUBUG: popped not succesful!");
> >         break;
> >       }
>
> > > If that doesn't solve it, I'd try tools, like valgrind.  Or running in
> > > a debugger, or enabling cores.
>
> > will try to use valgrind - don't know if it will run on my embedded
> > platform tho...
> > Debugger unfortunately will not be an option.... enabling cores - what
> > do you mean?
>
> > Thanks!
> > Ron
>
> A debugger's not an option? What is this, 1980? Have you thought about
> disabling the watchdogs?

Yes, well I've gotten overthis, disabling the watchdogs alone wouldn't
help, I needed to write a little KeepAlive application to provide a
heartbeat to the power supply so this would not cut the power when the
heartbeat isn't provided by my "main app" (cause it's stopped in a
debugger) - so we're good if you add 30 years, it's 2010 ;)

==============================================================================
TOPIC: Comparision of C Sharp and C performance
http://groups.google.com/group/comp.lang.c/t/4cf78a2afa73b77a?hl=en
==============================================================================

== 1 of 1 ==
Date: Thurs, Jan 7 2010 10:32 am
From: Nick <3-nospam@temporary-address.org.uk>


raltbos@xs4all.nl (Richard Bos) writes:

> Nick Keighley <nick_keighley_nospam@hotmail.com> wrote:
>
>> On 5 Jan, 08:45, Nick <3-nos...@temporary-address.org.uk> wrote:
>> > The Sinclair Spectrum is a nice example. =A0As a line was typed it was
>> > transformed: keywords were stored as single bytes (the top-half of the
>> > "character" set) - that they'd been typed in as special key-presses
>> > helped of course,
>>
>> it basically meant the user was doing the lexical analysis! As I
>> understood it if you typed "IF" (I assuming IF is a valid keyword in
>> Spectrum Basic) the the interpreter didn't understand you but if you
>> typed shift-bucky-I (the I key having the word "IF" on it as well)
>> then an "IF" was added to the program. The interpreter had its key
>> words pre-tokenised for it!
>
> You understand wrong. If you were at a point where the command entry
> routine wanted a keyword, you _could_ not type "IF". You pressed the 'U'
> key, and that would result, without any shift keys being needed, in the
> 'IF' keyword being entered. If you typed 'I' 'F' instead, you'd get
> 'INPUT' 'F'.
> As a side note, you could, and would, use symbol shift, but only to
> enter other grammatical parts of commands such as '<' or 'THEN' (and,
> anomalously, the 'STOP' keyword). You'd also use it combined with caps
> shift to enter "extended mode", in which you could enter less common
> keywords such as 'BEEP' or 'ABS'.
>
> In the end, though, it was a pure interpreter, but what you entered was
> whole keywords, not text. It was possible, by trickery, to get it to see
> the text "IF" rather than the keyword 'IF' where it expected a keyword,
> but it wouldn't accept the line if you did so.

The QL had a more conventional input system (plain text, not keywords)
but still did tokenisation and use of high-bit-set characters for
keywords. Every so often a bug could be triggered that turned every
keyword in your program in "PRINT".
--
Online waterways route planner | http://canalplan.eu
Plan trips, see photos, check facilities | http://canalplan.org.uk

==============================================================================
TOPIC: assert in C
http://groups.google.com/group/comp.lang.c/t/921be6a4718cfb1b?hl=en
==============================================================================

== 1 of 1 ==
Date: Thurs, Jan 7 2010 10:50 am
From: richard@cogsci.ed.ac.uk (Richard Tobin)


In article <87vdffkqks.fsf@gmail.com>, Gareth Owen <gwowen@gmail.com> wrote:

>> Programs that send error messages to stdout are a pain. If you're
>> running a pipeline of programs

>Can you do that with my program?

I've no idea. I assumed you were telling comp.lang.c what you do
because other people might find it useful. I'm telling them why it
might be a bad idea, which it is for most programs.

I must say the rest of your post is rather an overreaction!

-- Richard
--
Please remember to mention me / in tapes you leave behind.


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

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