Monday, March 29, 2010

comp.lang.c - 26 new messages in 9 topics - digest

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

comp.lang.c@googlegroups.com

Today's topics:

* Strange run time error - 6 messages, 5 authors
http://groups.google.com/group/comp.lang.c/t/26de5e1e7c96cfe0?hl=en
* 16:32 far pointers in OpenWatcom C/C++ - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c/t/4728dadef590aafe?hl=en
* Implementing strstr - 13 messages, 6 authors
http://groups.google.com/group/comp.lang.c/t/a3fe05ab352d5774?hl=en
* OT: Linux problem - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c/t/b27bbc7383c9d155?hl=en
* Pausing screen? - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c/t/8b8e7943a28d1f6c?hl=en
* Container library (continued) - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c/t/3763649cc890efcc?hl=en
* Wanted - example program to execute stack - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c/t/15477a0ce4b244e3?hl=en
* How to check data input - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c/t/47d80150d7d879a9?hl=en
* Computing a*b/c without overflow in the preprocessor - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c/t/1049c69de2e8ea27?hl=en

==============================================================================
TOPIC: Strange run time error
http://groups.google.com/group/comp.lang.c/t/26de5e1e7c96cfe0?hl=en
==============================================================================

== 1 of 6 ==
Date: Mon, Mar 29 2010 10:30 am
From: sandeep


Hello

I am reminding myself of C after many years. I have found a very strange
run time error, "Segmentation Fault", I don't remember ever seeing this.
There are no compiler errors! What is wrong with my code??

main(char * argv [], int argc)
{
char NAME[1024 * sizeof (char)] = {0}; // declare static array
// build up the output buffer
if ( strlen (argv[1]) > 1000 ) {
printf("Buffer overflow error please restart");
abort();
}
strcpy(NAME, "Hello ");
strcat(NAME, argv[1]);
strcat(NAME, " have a nice day");
// display the buffer
printf(NAME);
}


== 2 of 6 ==
Date: Mon, Mar 29 2010 10:41 am
From: Andrew Poelstra


On 2010-03-29, sandeep <nospam@nospam.com> wrote:
> Hello
>
> I am reminding myself of C after many years. I have found a very strange
> run time error, "Segmentation Fault", I don't remember ever seeing this.
> There are no compiler errors! What is wrong with my code??
>
> main(char * argv [], int argc)

int main(int argc, char *argv[])

This corrects two errors - one, the implicit int return
which is no longer valid C, and two, your parameters were
out of order.

Surely your compiler warned you of these things?

> {
> char NAME[1024 * sizeof (char)] = {0}; // declare static array

sizeof(char) == 1 by definition. I wish they had called char 'byte'
for this reason, so that actual character data (which IRL is more
than one byte per character now) could be represented in a char,
but they didn't.

The point is that:
char name[1024] = {0};
is just as valid, and clearer too.

> // build up the output buffer
> if ( strlen (argv[1]) > 1000 ) {

Whoa whoa whoa, what is argv[1]? Why do you assume such a thing
to exist? You need to check first, by making sure argc is > 1.
The C Standard says that argv[argc] is NULL, and passing NULL
to strlen gets you a segfault.

(Actually, it's undefined, but most modern OS's are kind enough to
simply shoot your program in the head at the point of dereference.)

Plus your main() parameters were backwards so you're screwed
no matter what.

> printf("Buffer overflow error please restart");

You're missing a \n at the end of this.

> abort();

exit(EXIT_FAILURE); is more idiomatic. You need to
#include <stdlib.h>
to get that constant.

> }
> strcpy(NAME, "Hello ");
> strcat(NAME, argv[1]);
> strcat(NAME, " have a nice day");

You can still overflow here, because if strlen(argv[1]) is > 981,
you won't have room for the rest of the text and the NUL-ending.
You only checked the length against 1000, which is insufficient.

> // display the buffer
> printf(NAME);

Where is your
return 0;
?

If you're going to use implicit int, at least do it properly.

> }

--
Andrew Poelstra
http://www.wpsoftware.net/andrew


== 3 of 6 ==
Date: Mon, Mar 29 2010 10:46 am
From: Ben Bacarisse


sandeep <nospam@nospam.com> writes:

> I am reminding myself of C after many years. I have found a very strange
> run time error, "Segmentation Fault", I don't remember ever seeing
> this.

It generally relates to invalid memory access.

> There are no compiler errors! What is wrong with my code??

You should try asking for more warnings. You may be using Linux with
gcc. If so try

gcc -std=c99 -pedantic -Wall -Wextra

> main(char * argv [], int argc)

int main(int argc, char *argv[])

You have the parameters the wrong way round.

> {
> char NAME[1024 * sizeof (char)] = {0}; // declare static array

This is not what most people call static array. It is, if you want to
categorise it, an automatic array.

sizeof (char) is 1 by definition and the name SHOUTS more than is
usual!

> // build up the output buffer
> if ( strlen (argv[1]) > 1000 ) {
> printf("Buffer overflow error please restart");
> abort();
> }

When you fix the first problem, this may still go wrong. You need to
test that argc > 1 or you can't pass argv[1] to strlen.

> strcpy(NAME, "Hello ");
> strcat(NAME, argv[1]);
> strcat(NAME, " have a nice day");
> // display the buffer
> printf(NAME);
> }

To use printf, you should include <stdio.h> and <string.h> for the
others. Many compilers will get you get away with it, but this is
just them being unhelpful.

--
Ben.


== 4 of 6 ==
Date: Mon, Mar 29 2010 11:27 am
From: Eric Sosman


On 3/29/2010 1:30 PM, sandeep wrote:
> Hello
>
> I am reminding myself of C after many years. I have found a very strange
> run time error, "Segmentation Fault", I don't remember ever seeing this.
> There are no compiler errors! What is wrong with my code??

Almost everything. To begin with, you're missing headers
for the library functions you call:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

> main(char * argv [], int argc)

Next problem: The parameters are backwards. It doesn't
matter what you name them, but the `int' must be first and
the `char**' second.

> {
> char NAME[1024 * sizeof (char)] = {0}; // declare static array

Next problem: This isn't a static array. (Not really a
"problem," in the sense that you don't actually need a static
array -- but if you think you're getting one, you're wrong.)

Next problem: There's no reason to initialize the array
to zeroes. It doesn't hurt anything, but it also doesn't help:
You're going to overwrite the array anyhow -- all of it that
you care about, at any rate.

Next problem: // is a syntax error in C90. It starts a
comment in C99, but we know you're not using a C99 compiler
(because such a compiler would have complained loudly about
the type-less definition of main() and about all the calls
to undeclared library functions.)

> // build up the output buffer

Same problem again: // is a syntax error.

> if ( strlen (argv[1])> 1000 ) {

Next problem: Even if you swap the parameters into the
right order, you don't know whether argv[1] exists unless you
first look at argc or at argv[0]. Even if argv[1] exists, it
might be a null pointer.

> printf("Buffer overflow error please restart");

Next problem: No \n character to end the line.

> abort();
> }
> strcpy(NAME, "Hello ");
> strcat(NAME, argv[1]);
> strcat(NAME, " have a nice day");
> // display the buffer
> printf(NAME);

Next problem: If argv[1] is something like "%solution"
this printf() call will go off the rails.

Next problem: Another absent \n.

Next problem: You fall off the end of int-valued main()
without returning a value. In C99 there's a special dispensation
that makes this equivalent to returning zero, but we know you're
not using C99.

> }

Final problem: All this strlen()-ing and strcat()-ing
is just plain silly. Once you've determined argv[1] exists

printf ("Hello %s have a nice day\n", argv[1]);

does the trick, safely, sleekly, and without all that foolish
mucking about.

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


== 5 of 6 ==
Date: Mon, Mar 29 2010 2:38 pm
From: rudolf


In article <hoqrh7$hgq$1@news.eternal-september.org>,
Eric Sosman <esosman@ieee-dot-org.invalid> wrote:

> Next problem: Even if you swap the parameters into the
> right order, you don't know whether argv[1] exists unless you
> first look at argc or at argv[0]. Even if argv[1] exists, it
> might be a null pointer.

How do you use argv[0] to check the presence of argv[1]?


== 6 of 6 ==
Date: Mon, Mar 29 2010 2:48 pm
From: Eric Sosman


On 3/29/2010 5:38 PM, rudolf wrote:
> In article<hoqrh7$hgq$1@news.eternal-september.org>,
> Eric Sosman<esosman@ieee-dot-org.invalid> wrote:
>
>> Next problem: Even if you swap the parameters into the
>> right order, you don't know whether argv[1] exists unless you
>> first look at argc or at argv[0]. Even if argv[1] exists, it
>> might be a null pointer.
>
> How do you use argv[0] to check the presence of argv[1]?

The array of command-line argument pointers is followed by
a null pointer, that is, argv[argc] == NULL. Therefore, if
argv[0] != NULL, argv[1] exists (it might be NULL, but it
exists).

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

==============================================================================
TOPIC: 16:32 far pointers in OpenWatcom C/C++
http://groups.google.com/group/comp.lang.c/t/4728dadef590aafe?hl=en
==============================================================================

== 1 of 1 ==
Date: Mon, Mar 29 2010 9:53 am
From: Michael Wojcik


Scott Lurndal wrote:
> [regarding requirements on pointer representations in C]
>
> Or does it require that the pointer be "binary"?
>
> Consider the following real-world, but old, architecture:
>
> Datatypes:
> Unsigned Numeric (1 to 100 digits BCD)
> Signed Numeric (1 to 100 digits BCD + leading BCD sign digit)
> Unsigned Alphanumeric (1 to 100 bytes (EBCDIC encoding))
>
> There are no general purpose registers, it's all memory to memory. There
> are 7 index registers that can be used as base registers for base+offset
> addressing. A region (segment effectively) of memory may contain
> 1,000,000 digits (500,000 bytes). Because there are 8 segments
> accessible at a time, a pointer to a memory location is a 7 digit
> signed value of the form CbOOOOOO where 'b' ranges from 0 to 7
> and designates which of the active segments to access, and OOOOOO
> is the offset within that segment. The index registers are loaded
> by the application as needed with a pointer of this form. Code
> is in segment one (architecturally enforced), the stack and other
> global data in segment 0; the other 6 segments are application
> defined. An application can switch to a different set of segments
> using the function call instruction, thus allowing access to
> eight million segments (albeit eight at a time, with special
> instructions available to move, compare or hash data betwen
> segments which may or may not be part of the active eight).
>
> So how does one map C to this architecture? Typically pointers
> in C are sized similarly to one of the fundamental types (int or
> long),

Typically, but not necessarily. The first several C implementations
for the AS/400 used 128-bit pointers exclusively; I believe the
current one supports both 128-bit (SLS) and 64-bit (TerraStore)
pointers (and JdBP posted as much a bit further back in this thread).

> which would imply that the C 'int' type should be defined
> as a 7-digit signed numeric field in memory, which would make
> INT_MAX 9999999 and INT_MIN -9999999.

This is already non-conforming. The Standard requires that the C
integer types use a pure binary representation, one of sign-magnitude,
1's-complement, or 2's-complement.

If you're implementing C on a non-binary machine, you have to
implement binary arithmetic on top of native arithmetic.

> Yet given the above, a pointer can only reference data shared between
> different segment 'environments' (i.e. groups of eight segments
> accessible at any one time). If one expands the pointer to
> include the environment (group of 8 segments) number, that makes
> a pointer 14 digits (6 digit environment number and 7 SN pointer),
> but only parts of the pointer would be used depending on context;

This, on the other hand, is fine. SLS pointers in AS/400 EPM C, System
C, and ILE C are structures that include data space, offset, and
validity information; C pointers do not have to be a linear index into
a flat (real or virtual) address space.

However, the implementation still has to make two representations of a
pointer visible to the program: one that's an array of unsigned char,
and one that's a printable string (for the %p format specifier). And
it has to be able to convert between those two representations and
whatever it uses internally.

(It does not, however, have to support a round-trip conversion if the
value is changed - that is, if a program gets one of those
representations, it can convert it back into a pointer, but only if it
hasn't altered it. And it's only a valid pointer if the object it
points to still exists.)

> Then, how does one tell the C compiler anything about segments,
> memory accessibility, etc.

That was the problem the AS/400 C implementations had to solve, though
fortunately there the integer types were binary, so that wasn't an
issue. And the platform already had SLS pointers (and the EPM
environment, used for the first C implementation, had already been
developed for use by Pascal), so much of the work had already been done.

AS/400 C was a bit of a surprise for people who thought they could
just cast between integer and pointer types willy-nilly, though. It
also had the nice feature of trapping if you called malloc without a
correct prototype in scope, because the default return type of int did
not accommodate a pointer.

But pointer handling on the AS/400 - a capability architecture with
single-level store, so all objects in the system are addressable by
all tasks, modulo permissions - is definitely interesting.

--
Michael Wojcik
Micro Focus
Rhetoric & Writing, Michigan State University

==============================================================================
TOPIC: Implementing strstr
http://groups.google.com/group/comp.lang.c/t/a3fe05ab352d5774?hl=en
==============================================================================

== 1 of 13 ==
Date: Mon, Mar 29 2010 10:37 am
From: Seebs


On 2010-03-29, blmblm myrealbox.com <blmblm@myrealbox.com> wrote:
> In article <40dc7174-2ab0-4818-aee3-8b9b22c0c4b6@l4g2000pro.googlegroups.com>,
> spinoza1111 <spinoza1111@yahoo.com> wrote:
>> > >> break to get out of the switch statement. As a result, a mkdir will do
>> > >> a mknod.

> You know, I looked briefly at the code in question, in

> http://github.com/wrpseudo/pseudo/blob/master/pseudo.c

> and to me it seems not to be doing either a mkdir *or* a mknod,
> but performing processing common to two cases identified as
> MKNOD and MKDIR. That there would be processing common to
> "make a directory (mkdir)" and "make a special file (mknod)" --
> it doesn't strike me as far-fetched or bad design. <shrug>

Exactly.

Actually, I could probably combine them fairly effectively with OP_CREAT,
too. The reason they're not the same is that MKNOD and MKDIR are the two
normal cases where a new entry is being created for something which is not
a plain file. CREAT is currently handled differently because I don't
necessarily assume that any existing file with the same inode is a bug,
but that may be a design flaw.

> I'm not sure it does, but perhaps the author of the code can clarify.

Both mknod and mkdir do "clear any previous entries with this path or
inode number, then store this new file in the database".

>> If this was useful, it exists coded by someone competent.

While there certainly are both fakeroot and fakeroot-ng, and I would not
choose to call the authors "incompetent", they do not solve the problems we
need solved, and retrofitting the functionality we want was impractical.

>> > What error? There is no possible error. by_ino and by_path are not
>> > pointers, they're objects. They are initialized at the top of the
>> > function. If data of either type have been found, we copy the best
>> > fit into db_header.

>> A competent programmer would know that under two circumstances, the
>> "data" DOESN'T HAVE to be be of "either" type. Either an external
>> error or a modification to the surrounding code would falsify this,
>> and as far as I can see you failed to plan for this.

You're quite right!

Similarly, when I write:

z = x + y;
z = z - y;
/* assume z = x */

I am not planning for the possibility of external changes.

Which is to say: There's a practical limit to how often you should recheck
that the code you just wrote hasn't changed. The only possible cases are:
1. Neither a matching path nor a matching inode was found.
We pick up the zeroed-out header.
2. Either a matching path or a matching inode was found, or both.
Use the best fit.

The only "external errors" that could occur would be for the find-by-inode
or find-by-path to fail, in which case, I'd think they had failed, leading
us towards case 1 above. Any modification to the surrounding code would,
indeed, require this to be changed. Yup. When I make changes within a
function to values used later in that function, sometimes I have to change
the way I use those values later in that function. OH WOE IS ME.

>> We're not talking about the later code. The upper code leaves
>> db_header with an undetermined value in the formal sense.

No, it doesn't. It leaves db_header with either a zeroed-out structure or
the best match found.

>> > I see no reason to assign it a null value, when I am guaranteed that
>> > I will always assign it one or another of two values, both of which
>> > are necessarily initialized.

>> But: you don't.

Except I do. Really, this isn't hard.

>> > There's no default handler because the function's spec is defined very
>> > clearly to never produce values other than the option characters specified,
>> > a question mark, or -1. Since -1 was handled above, ? is the only other
>> > possibility. I suppose I should have a default: case for the possible
>> > case where a new option is added to the option string but not to the switch
>> > statement, but it hasn't yet come up.

>> Great programmers anticipate even endogenous errors, meaning that they
>> code so that any statement that is not changed in a future release has
>> a high probability of still working when other statements are changed!

> Now this strikes me as a reasonable criticism. Seebs?

It actually sort of is! Admittedly, it's right only in a way that makes his
original criticism wrong, but yup, that's right. I've added a 'default' next
to the ?.

Apart from that, this is the usual sort of Nilges rant -- tons of compliants
based on totally misunderstanding basic idioms, and huge, epic, rants about
how I should be even more careful and paranoid. (Which I'm somewhat
sympathetic to just because for the most part, I take it as a personal
offense if pseudo manages to fail in a way that doesn't produce a clear
diagnostic as to what went wrong.)

-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 13 ==
Date: Mon, Mar 29 2010 10:40 am
From: Seebs


On 2010-03-29, blmblm myrealbox.com <blmblm@myrealbox.com> wrote:
> In article <2b515245-4679-4f8a-8fee-83eb024c73f6@f14g2000pre.googlegroups.com>,
> spinoza1111 <spinoza1111@yahoo.com> wrote:
>> On Mar 28, 5:49 am, Seebs <usenet-nos...@seebs.net> wrote:
>> > On 2010-03-27, blmblm myrealbox.com <blm...@myrealbox.com> wrote:
>> > > Experience suggests
>> > > that our brains don't all work the same in all respects, but now
>> > > I'm wondering which of us is the outlier ....

>> > Me.

> Maybe in the general population. Among those interested in programming,
> perhaps not?

Maybe not, but I don't know all that many ADHD programmers, and I'm on
the fringe so far as extremity of traits.

>> > It's a stereotypical trait of ADHD, especially fairly extreme
>> > ADHD. Basically, if I'm not fully engaged, my mind starts wandering
>> > fast -- and simple tasks aren't very engaging.

>> You'd never get an entry level job with Mies van Der Rohe.

Wow, Nilges was right about something!

Now, the key question is: Would I care?

> Hm. What you apparently perceive as a plea for sympathy or
> special treatment I perceive as a simple statement of fact.
> That probably shouldn't surprise me, though, given that I also
> perceived the long-ago statement about not having taken any CS
> classes as a simple statement of fact, while you have repeatedly
> called it a boast.

Exactly. I'm not expecting sympathy or praise, merely explaining how it
comes to be that I find hard things easier than easy things.

Basically, my brain's only marginally useful outside of flow*. The tradeoff
is that, once I am in a working state, I'm extremely good. Obviously, this
imposes some limits on my choice of jobs or lifestyles. So I adapt to those
limits, because what else would I do?

-s
[*] http://en.wikipedia.org/wiki/Flow_(psychology)
--
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 13 ==
Date: Mon, Mar 29 2010 10:44 am
From: Seebs


On 2010-03-29, blmblm myrealbox.com <blmblm@myrealbox.com> wrote:
> In article <30e391ad-84bb-435f-b058-f718d3dec372@t9g2000prh.googlegroups.com>,
> spinoza1111 <spinoza1111@yahoo.com> wrote:
>> You've never taught English in China. It's offensive to people with
>> good English as a second language to use idioms in the cutesy way of
>> unix man pages.

> Is it really ("offensive") ....

It is not. Part of the point of developing *good* <language> as a second
language is to develop familiarity with idioms.

And yes, I do feel competent to talk on the issue, as:
1. I spent a year in China while my mom was coaching people for the TOEFL
and GRE, and we discussed effective teaching techniques.
2. A large number of my coworkers are Chinese, and have thanked me greatly
for using and explaining idioms, because it helps them understand real-world
usage of English. (I think the thanks may be more tied to the explaining
than to the use, but they don't seem to find the use offensive; rather, they
view it as an opportunity for learning.)

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


== 4 of 13 ==
Date: Mon, Mar 29 2010 10:45 am
From: Seebs


On 2010-03-29, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
> What is (at first glance) a little odd is that two explicit cases have
> been added to a default cause. One has to ask if the added
> documentary value in making these explicit is worthwhile. I'd say
> that it is -- particularly if all switch statements that switch on the
> message type explicitly include these four cases.

Most of the time (but not always), I test for every defined value
(usually excluding things like FOO_NONE or FOO_MAX) explicitly, and "default"
is there to handle the possibility that a value not in the defined range
at all will occur.

-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 13 ==
Date: Mon, Mar 29 2010 11:51 am
From: Nick <3-nospam@temporary-address.org.uk>


Seebs <usenet-nospam@seebs.net> writes:

> Basically, my brain's only marginally useful outside of flow*. The tradeoff
> is that, once I am in a working state, I'm extremely good. Obviously, this
> imposes some limits on my choice of jobs or lifestyles. So I adapt to those
> limits, because what else would I do?

Well you could post thousands of lines a day to comp.lang.c about how
the world isn't structured exactly the way you want it to be, and about
how no-one else uses words in the same humpty-dumpty fashion you do, and
about bizarre industrial relations history of the 1970s and why that
means some programming languages follow paradigms invented by medieval
painters (I may have got the last of these a bit wrong). It seems to
work for at least one person.
--
Online waterways route planner | http://canalplan.eu
Plan trips, see photos, check facilities | http://canalplan.org.uk


== 6 of 13 ==
Date: Mon, Mar 29 2010 12:17 pm
From: Seebs


On 2010-03-29, Nick <3-nospam@temporary-address.org.uk> wrote:
> Well you could post thousands of lines a day to comp.lang.c about how
> the world isn't structured exactly the way you want it to be, and about
> how no-one else uses words in the same humpty-dumpty fashion you do, and
> about bizarre industrial relations history of the 1970s and why that
> means some programming languages follow paradigms invented by medieval
> painters (I may have got the last of these a bit wrong). It seems to
> work for at least one person.

Good thought!

Actually, I think I'm gonna take advantage of being on my lunch break
to write up my own implementation of strstr(), plus a test harness.

Because, hey, it'll be fun. And I'm sure that the various funny mistakes
I make in the process will amuse.

-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 13 ==
Date: Mon, Mar 29 2010 12:27 pm
From: Squeamizh


On Mar 27, 1:52 pm, Seebs <usenet-nos...@seebs.net> wrote:
> On 2010-03-27, blmblm  myrealbox.com <blm...@myrealbox.com> wrote:
> > In article <52ae4a94-4361-417c-871d-a72b9fbde...@t17g2000prg.googlegroups.com>,
> > spinoza1111  <spinoza1...@yahoo.com> wrote:
> (Thanks for quoting this, I never see his garbage except when quoted.)

You killfiled spinoza so that you don't have to see his garbage. Then
you thank someone for quoting his garbage and circumventing your
killfile. I suggest you remove spinoza from your killfile.


== 8 of 13 ==
Date: Mon, Mar 29 2010 12:53 pm
From: Seebs


Okay, this sounded fun. Here's a trivial test harness and a trivial strstr.
Feel free to find bugs. The only one I caught in testing was that I had
the order of the two arguments reversed -- I did (needle, haystack) rather
than (haystack, needle). Feel free to present broken cases; I have no
illusions that I'll have gotten this bug-free on the first try.

This program assumes that the library strstr() works.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *my_strstr(const char *s1, const char *s2);

/* for test harness, not for implementation */
#define MAX_LEN 128

/* imagine that a large buffer is divided into five parts:
* 1 2 3 4 5
* test_strstr() copies the argument strings into slots 2 and 4, so
* that results can be compared for relative position, not just equality,
* because they're all in a single argument.
*/
void
test_strstr(char *haystack, char *needle) {
size_t needle_len, haystack_len;
char big_buffer[MAX_LEN * 5] = { 0 };
char *store_needle = big_buffer + (MAX_LEN * 1);
char *store_haystack = big_buffer + (MAX_LEN * 3);

char *lib_return, *my_return;

if (!needle || !haystack) {
fprintf(stderr, "error: test_strstr() needs valid strings.\n");
return;
}
needle_len = strlen(needle);
haystack_len = strlen(haystack);
if (needle_len > 128) {
fprintf(stderr, "test_strstr: needle too long (limit %d)\n",
MAX_LEN);
return;
}
if (haystack_len > 128) {
fprintf(stderr, "test_strstr: haystack too long (limit %d)\n",
MAX_LEN);
return;
}
strcpy(store_needle, needle);
strcpy(store_haystack, haystack);
lib_return = strstr(store_haystack, store_needle);
my_return = my_strstr(store_haystack, store_needle);

printf("test: <%s> in <%s>: ",
store_needle, store_haystack);
if (lib_return == my_return) {
if (lib_return)
printf("<%s> (offset %d).\n",
lib_return, lib_return - store_haystack);
else
printf("No match.\n");
return;
}
/* they don't match... what went wrong? */
if (!my_return) {
printf("I found no match, lib found <%s> (offset %d).\n",
lib_return, lib_return - store_haystack);
return;
}
if (my_return < store_haystack) {
printf("return (%p) underruns haystack (%p - %p)?\n",
(void *) my_return, (void *) store_haystack,
(void *) (store_haystack + haystack_len));
return;
}
if (my_return > store_haystack + haystack_len) {
printf("return (%p) overruns haystack (%p - %p)?\n",
(void *) my_return, (void *) store_haystack,
(void *) (store_haystack + haystack_len));
return;
}
/* so at this point, my_return is non-null and in the haystack */
if (!lib_return) {
printf("lib found no match, I found <%s> (offset %d).\n",
my_return, my_return - store_haystack);
}
printf("lib/my return mismatch:\n");
printf("\tlib: <%s> at %d\n", lib_return, lib_return - store_haystack);
printf("\tme: <%s> at %d\n", my_return, my_return - store_haystack);
}

char *
my_strstr(const char *haystack, const char *needle) {
const char *found = 0;
const char *next_candidate = 0;
const char *h, *n;

/* an empty string is found immediately, even in an empty string */
if (!*needle)
found = haystack;
for (; !found && *haystack; ++haystack) {
if (*haystack == *needle) {
next_candidate = 0;
h = haystack;
n = needle;
/* stash the next spot matching the first
* character of the needle.
*/
while (*++n == *++h) {
if (*n == *haystack && !next_candidate)
next_candidate = h;
}
/* we reached the end of the needle, so
* we are done
*/
if (!*n) {
found = haystack;
} else {
if (next_candidate)
haystack = next_candidate - 1;
else
haystack = h - 1;
}
}
}

/* sorry, no way around it; we can't return a possibly-qualified
* pointer, so we have to drop const in case the original strings
* were not really const.
*/
return (char *) found;
}

int
main(void) {
test_strstr("foobar", "foo");
test_strstr("foobar", "bar");
test_strstr("foobar", "baz");
test_strstr("banana", "na");
test_strstr("bananas", "nas");
test_strstr("iced tea", "a");
test_strstr("blah", "");
return 0;
}

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


== 9 of 13 ==
Date: Mon, Mar 29 2010 1:41 pm
From: Keith Thompson


Squeamizh <squeamz@hotmail.com> writes:
> On Mar 27, 1:52 pm, Seebs <usenet-nos...@seebs.net> wrote:
>> On 2010-03-27, blmblm  myrealbox.com <blm...@myrealbox.com> wrote:
>> > In article <52ae4a94-4361-417c-871d-a72b9fbde...@t17g2000prg.googlegroups.com>,
>> > spinoza1111  <spinoza1...@yahoo.com> wrote:
>> (Thanks for quoting this, I never see his garbage except when quoted.)
>
> You killfiled spinoza so that you don't have to see his garbage. Then
> you thank someone for quoting his garbage and circumventing your
> killfile. I suggest you remove spinoza from your killfile.

Or keep him there and stop replying to him. Your call.

--
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 13 ==
Date: Mon, Mar 29 2010 1:46 pm
From: Seebs


On 2010-03-29, Keith Thompson <kst-u@mib.org> wrote:
> Squeamizh <squeamz@hotmail.com> writes:
>> On Mar 27, 1:52�pm, Seebs <usenet-nos...@seebs.net> wrote:
>>> On 2010-03-27, blmblm �myrealbox.com <blm...@myrealbox.com> wrote:
>>> > In article <52ae4a94-4361-417c-871d-a72b9fbde...@t17g2000prg.googlegroups.com>,
>>> > spinoza1111 �<spinoza1...@yahoo.com> wrote:
>>> (Thanks for quoting this, I never see his garbage except when quoted.)

>> You killfiled spinoza so that you don't have to see his garbage. Then
>> you thank someone for quoting his garbage and circumventing your
>> killfile. I suggest you remove spinoza from your killfile.

> Or keep him there and stop replying to him. Your call.

Actually, I like it the way it is -- I get a filtered feed of an occasional
actual technical question, without the flood of irrelevant insults.

The guy's unambiguously a usenet kook, but his questions on technical
issues are occasionally interesting, for much the same reason that it
can be occasionally interesting to try to answer questions asked by
other novice-level programmers. It's just not very rewarding to me
to search through several-hundred line posts full of tinfoil hat nonsens
to find an occasional gem like his observation that there should be
a default case in a getopt() switch because someone could modify the
argument string but not remember to add the corresponding case. That
was actually a good idea, I think.

So I appreciate it when people who have more patience with his rambling
nonsense than I do filter out the occasional things worth responding to
and make them noticeable.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!


== 11 of 13 ==
Date: Mon, Mar 29 2010 3:49 pm
From: Tim Streater


In article <87634fneq7.fsf@temporary-address.org.uk>,
Nick <3-nospam@temporary-address.org.uk> wrote:

> Seebs <usenet-nospam@seebs.net> writes:
>
> > Basically, my brain's only marginally useful outside of flow*. The tradeoff
> > is that, once I am in a working state, I'm extremely good. Obviously, this
> > imposes some limits on my choice of jobs or lifestyles. So I adapt to those
> > limits, because what else would I do?
>
> Well you could post thousands of lines a day to comp.lang.c about how
> the world isn't structured exactly the way you want it to be, and about
> how no-one else uses words in the same humpty-dumpty fashion you do, and
> about bizarre industrial relations history of the 1970s and why that
> means some programming languages follow paradigms invented by medieval
> painters (I may have got the last of these a bit wrong). It seems to
> work for at least one person.

Good summary of Baldrick's personality disorders. And it would be nice
if he stopped posting his turgid "poetry" which is offensive to those of
us with English as a mother tongue, never mind everyone else.

--
Tim

"That excessive bail ought not to be required, nor excessive fines imposed,
nor cruel and unusual punishments inflicted" -- Bill of Rights 1689


== 12 of 13 ==
Date: Mon, Mar 29 2010 2:51 pm
From: Ben Bacarisse


Seebs <usenet-nospam@seebs.net> writes:

> Okay, this sounded fun. Here's a trivial test harness and a trivial strstr.
> Feel free to find bugs.
<snip>

I did not look at the tester.

> char *
> my_strstr(const char *haystack, const char *needle) {
> const char *found = 0;
> const char *next_candidate = 0;
> const char *h, *n;
>
> /* an empty string is found immediately, even in an empty string */
> if (!*needle)
> found = haystack;
> for (; !found && *haystack; ++haystack) {
> if (*haystack == *needle) {
> next_candidate = 0;
> h = haystack;
> n = needle;
> /* stash the next spot matching the first
> * character of the needle.
> */
> while (*++n == *++h) {

Possible UB from running off the end of one or both strings here. If
the arrays have further characters after matching nulls, then you
don't get UB but the algorithm goes wrong.

> if (*n == *haystack && !next_candidate)
> next_candidate = h;
> }
> /* we reached the end of the needle, so
> * we are done
> */
> if (!*n) {
> found = haystack;
> } else {
> if (next_candidate)
> haystack = next_candidate - 1;
> else
> haystack = h - 1;
> }
> }
> }
>
> /* sorry, no way around it; we can't return a possibly-qualified
> * pointer, so we have to drop const in case the original strings
> * were not really const.
> */
> return (char *) found;
> }

<snip>
--
Ben.


== 13 of 13 ==
Date: Mon, Mar 29 2010 2:49 pm
From: Seebs


On 2010-03-29, Tim Streater <timstreater@waitrose.com> wrote:
> Good summary of Baldrick's personality disorders. And it would be nice
> if he stopped posting his turgid "poetry" which is offensive to those of
> us with English as a mother tongue, never mind everyone else.

Well-written doggerel can be a real pleasure to read. Sadly, working with
John Nash does not make you Ogden Nash.

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

==============================================================================
TOPIC: OT: Linux problem
http://groups.google.com/group/comp.lang.c/t/b27bbc7383c9d155?hl=en
==============================================================================

== 1 of 1 ==
Date: Mon, Mar 29 2010 10:47 am
From: Seebs


On 2010-03-29, jacob navia <jacob@nospam.org> wrote:
> No I can't. There is no debugger. I just want something that will write a
> stack trace and register dump to a log file at the customer site...
>
> I know gdb but this is not possible.

There's code in glibc to do a little bit of this, but a register dump really
MUST be done by some other program.

Anyway, what you probably *really* want is a core file. A lot of modern
Linux systems turn off coredumps by default, but if you turn them back on,
you get a file which has not only stack and registers, but the complete
memory image of the executable, allowing you to use gdb at your leisure
to explore the various stack frames.

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

==============================================================================
TOPIC: Pausing screen?
http://groups.google.com/group/comp.lang.c/t/8b8e7943a28d1f6c?hl=en
==============================================================================

== 1 of 1 ==
Date: Mon, Mar 29 2010 11:42 am
From: Zach


On Mar 28, 5:38 pm, Richard Heathfield <r...@see.sig.invalid> wrote:
> Zach wrote:
> > When I compile a C program in Dev-C++ (www.bloodshed.net) or in
> > Microsoft Visual Studio 8 Express it will flash a DOS window with the
> > results and then immediately close! How can I pause the screen?
>
> If you're running in debug mode, simply set a breakpoint on main's
> return statement. If you're wise enough to follow the one-entry one-exit
> rule every time (i.e. don't have any exit() calls), this will work every
> time - except in the case of an assertion, but that's okay because if
> you get an assertion failure the IDE is already pretty good at getting
> you the information you need.
>
> If you're running in release mode, VStudio already retains the console
> window until you press a key, so you don't get the problem in the first
> place.
>
> If you're running from the console, you still don't get the problem in
> the first place.
>
> Given the above options, putting a "press me to quit" into your program
> is simply daft, so don't do it. If you *do* do it, you'll regret it when
> you release your code - either you'll take it out, in which case you'll
> be forever putting it in and taking it out whenever you have to maintain
> the code, or you'll leave it in, in which case your users will curse
> your name every time they try to use your program as a filter.
>
> "Interactive" is just another word for "manual". Don't give the user
> extra work.

Thanks Richard and everyone who helped me with this problem.

Zach

==============================================================================
TOPIC: Container library (continued)
http://groups.google.com/group/comp.lang.c/t/3763649cc890efcc?hl=en
==============================================================================

== 1 of 1 ==
Date: Mon, Mar 29 2010 2:12 pm
From: raltbos@xs4all.nl (Richard Bos)


"bartc" <bartc@freeuk.com> wrote:

> "ng2010" <ng2010@att.invalid> wrote in message
>
> > The new languages are coming, I assure you.
>
> Which languages are these?

Java and NewBASIC.

Richard

==============================================================================
TOPIC: Wanted - example program to execute stack
http://groups.google.com/group/comp.lang.c/t/15477a0ce4b244e3?hl=en
==============================================================================

== 1 of 1 ==
Date: Mon, Mar 29 2010 2:26 pm
From: "Dr. David Kirkby"


On Mar 29, 5:13 pm, jacob navia <ja...@nospam.org> wrote:
> Dr. David Kirkby a crit :
>
>
>
> > On Mar 29, 10:22 am, jacob navia <ja...@nospam.org> wrote:
> >> Dr. David Kirkby a crit :
>
> >>> Can anyone give me a noddy example of a C program that tries to
> >>> execute the stack? I want to create a test to see if an operating
> >>> system is configured with stack protection or not.
> >>> Apparently on SELinux one can use 'setstatus' to determine if stack
> >>> protection is in operation or not, but I'd like a test which avoided
> >>> having to find a test for each platform, if a program could be made to
> >>> test it.
> >>> The The Number Theory Library (NTL) is one application which tries to
> >>> execute the stack and causes problems if stack protection is in use. I
> >>> suspect this is a bug in NTL, though it might be done for speed
> >>> reasons - lots of highly optimised maths code does unusual things.
> >>> Dave
> >> For x86 architectures:
>
> >> typedef void(*voidfn)(void);
> >> int main(void)
> >> {
> >>         char a[2] = {0xc3,0};
> >>         voidfn fnptr = (voidfn)a;
> >>         fnptr();
>
> >> }
>
> >> If that works and doesn't crash there is NO stack execution protection.
>
> > Thank you very much. I tested this on my OpenSolaris 06/2009 (quad
> > core Intel Xeon) workstation and it behaves as you say. First the
> > program did not crash, then when I set:
>
> > set noexec_user_stack=1
> > set noexec_user_stack_log=1
>
> > in /etc/system (which enables stack protection), so it crashed.
>
> > I must admit, I don't fully understand why it works, so any help on
> > that matter would be appreciated.
>
> I build a one instruction function that executes a "return"
> Since the instruction is in the stack, if you can execute instructions
> in the stack it doesn't crash, but if stack execution prevention is on
> it will crash.
>
> The return instruction just tells the processor to return to the calling procedure
> (main)
>
> jacob

Thank you very much. That is helpful.

I can't see to find the opcode for return on SPARC. I know there is a
'ret' instruction, but I'm stuck there. Is there any way I could
compile a C program to see what the opcode of the return statement is
on SPARC? I tried using gcc -S, but the assebly code only had a 'ret'
in it so not much help. I can't seem to find it on the Sun (now
Oracle) web site. Perhaps sparc.org might have something.

dave

==============================================================================
TOPIC: How to check data input
http://groups.google.com/group/comp.lang.c/t/47d80150d7d879a9?hl=en
==============================================================================

== 1 of 1 ==
Date: Mon, Mar 29 2010 2:28 pm
From: Peter Nilsson


Keith Thompson <ks...@mib.org> wrote:
> Dr Malcolm McLean <malcolm.mcle...@btinternet.com> writes:
> > ... Richard's advice to avoid scanf() is good. It's hard
> > to write a bulletproof interface with scanf() that will
> > react correctly to all user errors.
>
> In fact, I believe it's impossible, at least if you use the
> numeric input formats such as "%lx".  If the value being
> read is outside the range of the target type, the behavior
> is undefined.

The behaviour of %8lx is certainly well defined.

The only real problem with scanf is that most input conversion
specifiers will ignore leading whitespace, including new-lines.

--
Peter

==============================================================================
TOPIC: Computing a*b/c without overflow in the preprocessor
http://groups.google.com/group/comp.lang.c/t/1049c69de2e8ea27?hl=en
==============================================================================

== 1 of 1 ==
Date: Mon, Mar 29 2010 2:52 pm
From: Francois Grieu


Hello,

I want to devise a C89 preprocessor macro MULDIV(a,b,c) which, given positive integer constant expressions a b c, produce an integer constant expression evaluable by the preprocessor and equal to a*b/c even though a*b might grossly overflow the range of long. I can assume a, b, c, a*b/c are all in range [1..2000000000].

I came up with something that works well enough for my current application, by combining two techniques:

1) Basic arithmetic tells that
a*b/c == ((a/c)*c + a%c) * b) / c
== (a/c)*b + (a%c)*((b/c)*c + b%c))/c
== (a/c)*b + (b/c)*(a%c) + (a%c)*(b%c)/c

This is enough to solve the problem when c<46342:

#define MULDIV1(a,b,c) ( ((a)/(c))*(b) + (b)/(c)*((a)%(c)) + \
((a)%(c))*((b)%(c))/(c) )

#if MULDIV1(18536400,4634100,46341)!=1853640000
#error "MULDIV1(18536400,4634100,46341) fails"

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home


Real Estate