dice generator problems

  • Thread starter Bill Cunningham
  • Start date
B

Ben Bacarisse

Ben Pfaff said:
Ben Bacarisse said:
Bill Cunningham said:
if (argv[1][0] == '-' && argv[1][1] == 'a') {
if ((x = strtol(argv[1], NULL, 10)) == LONG_MIN || LONG_MAX) {

This is wrong but it not (currently) a problem because errors prevent
compilation. You want x == LONG MAX at the end, not just LONG_MAX.

"x == LONG MAX"?

saved by the "just", I think :)
 
K

Keith Thompson

Seebs said:
You need to slow down, and possibly stop drinking while posting.

None of this has anything to do with the distinction between comparison
and assignment.

I really don't understand why you're still doing this. If you can't
understand the explanation you were just given, there is no *point*.
Do you have alexia or something?

He's said he's suffering from the side effects of some medication he's
taking; I don't remember the details.

It's also been suggested that he's a deliberate troll. If so, he's
quite skilled at it. (This does not imply any kind of admiration on
my part; if he's deliberately trolling, it's pathetic, not admirable.)

In any case, he's been trying to learn C programming for many years.

No, it didn't.
But that's not the question.


Right. Which is documented, too, if you would read the standard, or a C
book, or pretty much anything else.

To be fair, I just checked the index of K&R2 for LONG_MAX and
LONG_MIN. It points to page 252, in the standard library reference,
which contains the description of strtol. It mentions that strtol
returns LONG_MIN or LONG_MAX on overflow, but it doesn't say where
they're defined.

That index entry should really point to page 257. (Bill, I think you
have a copy of K&R2, so that's a big hint.)

The online man page Bill cited is also a bit misleading. It says:

LEGACY SYNOPSIS

#include <stdlib.h>
#include <limits.h>

<limits.h> is necessary for the strtol() and strtoll() functions.

(Note that if Bill had followed this advice he wouldn't be having this
problem, though he still wouldn't know where strtol, LONG_MIN, and
LONG_MAX are actually declared).
 
N

Nick Keighley

Keith Thompson said:
Bill Cunningham said:
        if ((x = strtol(argv[1], NULL, 10)) == LONG_MIN || LONG_MAX) {
x == 1 || 2
is not a test for whether x is equal to either 1 or 2.

Mr Seebach is giving an example of code that is simpler than yours BUT
ALSO WRONG IN THE SAME WAY.


which bit didn't you understand?

x == 1 || 2
does not test if x is either 1 or 2 does it? Write a test program if
you have difficulty understanding.
    I should have used = instead of ==

what does the operator == do? what does the operator = do? Which one
would you use if you wanted to test if two things were equal.

I think I'd be better off teaching my cat to program in C.

<snip>
 
S

Squeamizh

Interesting trivia point:  I have written substantial code in a language
where

Your trivia point would be more interesting if you named the
language. I've seen you and others do this kind of thing quite a bit,
and I have never understood it. "There is at least one platform on
which your code wouldn't run correctly," "There is at least one
popular compiler that doesn't implement feature <x> that way," and so
on. The information might be somewhat interesting, but it's useless
without specifics. You took the time to describe something, but you
left out the most important detail!
 
N

Nick Keighley

Your trivia point would be more interesting if you named the
language.  

only slightly. in what way does it relate to C programming? Why not
just on comp.programming and ask "what language has a syntax of X"?
I've seen you and others do this kind of thing quite a bit,
and I have never understood it.  "There is at least one platform on
which your code wouldn't run correctly," "There is at least one
popular compiler that doesn't implement feature <x> that way,"

it's a math thing. Once you've produced one counter-example you've
destroyed the hypothesis/claim.

Why does it matter if the platform is an IBM mainframe or a DSP chip
(which both do rather odd things, or so we "all the worlds a VAX"
people think)?

I think its usually good enough that there /exists/ a a counter
example.

"A pointer won't fit in an int" "it doesn't have to be 2s complement"
"a pointer isn't always a simple number" "char* might not be the same
size as int*"
and so
on.  The information might be somewhat interesting, but it's useless
without specifics.  You took the time to describe something, but you
left out the most important detail!

opinions vary.
 
F

Frank

In


But in mathematics, saying "I have a counter-example" is not
sufficient. You have to produce the counter-example. The point here
is not to prove that a given construct is not portable by producing a
counter-example, because we don't need one - we have the Standard for
that. No, the point - and this only works if the point-maker is
someone you trust not to lie to you - is to point out the danger of
using the construct. Naming a platform where the technique does not
work would most likely draw a reaction of "but I don't suppose my
code will ever run on that platform", which would be fair enough
except for the fact that the program /may/ one day have to run on
some other platform that shares the same issue. If that definitely
isn't a concern, fine, go ahead and use the construct - portability
is only one of several conflicting factors that we face with every
non-trivial program we write.

<snip>

Well, Richard, I trust you to be well ahead of the curve on C issues while
completely unrealistic about platform and portability isues.

My best first dice generator was in fortran.
 
K

Kenny McCormack

Your trivia point would be more interesting if you named the
language. I've seen you and others do this kind of thing quite a bit,
and I have never understood it. "There is at least one platform on
which your code wouldn't run correctly," "There is at least one
popular compiler that doesn't implement feature <x> that way," and so
on. The information might be somewhat interesting, but it's useless
without specifics. You took the time to describe something, but you
left out the most important detail!

Welcome to CLC! We hope you enjoy your stay!

You have now been exposed to the CLC way - which is never to say
anything specific - that is to say, testable. Because if you do,
someone will call you on it, and show that you are wrong. The rules of
CLC are such that anything can be sub-divided and looked at in such a
way as to be wrong.

So, smart people avoid saying anything specific. It is all vague
references, such as you quote above.

Again, we hope you enjoy your stay!
 
B

Barry Schwarz

He's said he's suffering from the side effects of some medication he's
taking; I don't remember the details.

It's also been suggested that he's a deliberate troll. If so, he's
quite skilled at it. (This does not imply any kind of admiration on
my part; if he's deliberately trolling, it's pathetic, not admirable.)

In any case, he's been trying to learn C programming for many years.

It's kind of strange that he doesn't seem to have these problems in
other newsgroups he posts to when he is really interested in solving
the problem.
 
B

Bill Cunningham

To be fair, I just checked the index of K&R2 for LONG_MAX and
LONG_MIN. It points to page 252, in the standard library reference,
which contains the description of strtol. It mentions that strtol
returns LONG_MIN or LONG_MAX on overflow, but it doesn't say where
they're defined.

That index entry should really point to page 257. (Bill, I think you
have a copy of K&R2, so that's a big hint.)

The online man page Bill cited is also a bit misleading. It says:

LEGACY SYNOPSIS

#include <stdlib.h>
#include <limits.h>

<limits.h> is necessary for the strtol() and strtoll() functions.

(Note that if Bill had followed this advice he wouldn't be having this
problem, though he still wouldn't know where strtol, LONG_MIN, and
LONG_MAX are actually declared).

I have used strtol before Keith and I've never used limits.h myself. And
I've never heard of the LONG... macros until I actually looked at my man
page. Could I use 0 to report an error? I might just use atoi instead.

Bill
 
K

Keith Thompson

Bill Cunningham said:
I have used strtol before Keith and I've never used limits.h
myself. And I've never heard of the LONG... macros until I actually
looked at my man page. Could I use 0 to report an error? I might
just use atoi instead.

Ok, you've never used limits.h before. So you can use it now.
Just add "#include <limits.h>" to the top of your program.
It's trivial.

You were trying to use LONG_MAX and LONG_MIN. Several of us assumed
that it would be very easy to find out where they're defined,
but it turned out to be more difficult than we thought (the man
page you cited wasn't clear, and the index of K&R2 points to the
wrong place). You probably could have checked some other reference
or done a Google search, but whatever.

You now know that LONG_MAX and LONG_MIN are defined in <limits.h>
and the strtol function is declared in <stdlib.h>. Your question
has been answered.

Could you use 0 to report an error? I suppose so, but why on Earth
would you want to? 0 is typically a valid value.

You could use atoi if you wanted to, but you'd lose the possibility
of any real error checking, and you'd be throwing away all the
work you've done trying to use strtol. In a real-world program,
strtol is the right function to use here. If you give up now,
everything you've done so far will have been a collosal waste of
time, yours as well as ours. (It may have been anyway.)

Have you even *tried* to fix the errors in your program, or are you
just going to drop it and come back later with some other problem?

Fix your code or stop wasting our time.
 
B

Ben Bacarisse

Squeamizh said:
Your trivia point would be more interesting if you named the
language.

Unlikely to be what Seebs is talking about, but icon has this pattern
though not the exact syntax quoted. In icon you can say

i == (1 | 2)

to ask is i is 1 or 2 (the parentheses are needed). You can even say:

(x | y | z) == (1 | 2)

to find out is any of x, y or z are either 1 or 2.

<snip>
 
K

Kenny McCormack

Keith Thompson said:
Fix your code or stop wasting our time.

Oh, come on. You love it!

If Bill ever stops wasting your time, you'll have to actually look into
this thing, we, what do they call it, oh yeah, I remember now: a life!
 
K

Kenny McCormack

Unlikely to be what Seebs is talking about, but icon has this pattern
though not the exact syntax quoted. In icon you can say

i == (1 | 2)

to ask is i is 1 or 2 (the parentheses are needed). You can even say:

(x | y | z) == (1 | 2)

to find out is any of x, y or z are either 1 or 2.

Many languages (though not low-level ones like C) had an "in" operator.
For example, SQL:

WHERE fld in (a,b,c)
 
P

Peter Nilsson

Richard Heathfield said:
But in mathematics, saying "I have a counter-example" is not
sufficient. You have to produce the counter-example.

Or use the axiom of choice to show one exists, without
necessarily producing it.
 
N

Nick

Bill Cunningham said:
I had one error in this code until I tried to use error checking with
strtol. Now I've really goofed it. This is the compilation I used.

gcc -g di.c -o a -ansi -pedantic -Wall

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

int main(int argc, char *argv[])
{
if (argc > 4 || argc == 0) {
fputs("Dice generator usage error\n", stderr);
exit(EXIT_FAILURE);
}
int x, y;
if (argv[1][0] == '-' && argv[1][1] == 'a') {
if ((x = strtol(argv[1], NULL, 10)) == LONG_MIN || LONG_MAX) {
fputs("strtol error\n", stderr);
return 1;
}
if ((y = strtol(argv[2], NULL, 10)) == LONG_MIN || LONG_MAX) {
fputs("strtol error\n", stderr);
return 1;
}
printf("%i\n", x + y);
exit(1);
}
srand(time(NULL));
printf("%i\n", rand(void) %argv[1]);
return 0;
}

Even when the bugs others have talked about have been shaken out, that's
not the most useful error checking you are doing there.

You'll only get LONG_MAX or LONG_MIN if you put a valid number into
strtol that is greater than the range of a long. Yet you end up putting
the result into an int - so there will be a great range of numbers out
of range that (assuming longs are bigger than ints on your platform)
that pass the test but don't fit into x or y.

Secondly, the LONG_xxx tests won't pick up the most common input error.
If the string is, for example, "seven" it will be accepted as valid, but
x will be set to 0. You need to use the middle parameter of strtol for
this.

In passing, for others, when I'm assigning strtol to an int is one of
the few times I use a not-entirely-necessary cast. It shows the reader
that I'm aware that I'm doing it (because I "know" the input will be in
range of an integer - for example I've assembled two hex digits in a
buffer).
 
I

Ike Naar

You'll only get LONG_MAX or LONG_MIN if you put a valid number into
strtol that is greater than the range of a long.

You'll also get LONG_MAX or LONG_MIN if you put LONG_MAX,
resp. LONG_MIN into strtol.
 
K

Keith Thompson

You'll also get LONG_MAX or LONG_MIN if you put LONG_MAX,
resp. LONG_MIN into strtol.

Right. To distinguish whether LONG_MIN or LONG_MAX indicates an
overflow, you need to set errno to 0 before the call and check its
value after the call. (If you don't set it to 0 before the call,
you risk the possibility that errno had already been set to ERANGE
by something else; standard functions don't set errno to 0.)
 
N

Nick

You'll also get LONG_MAX or LONG_MIN if you put LONG_MAX,
resp. LONG_MIN into strtol.

True, thanks. As has been said many times before, catching all errors
is complicated, even with strtol to help.

Practically, I think that's the least of the problems
here: and limiting the number of dice that generated to LONG_MAX-1 isn't
going to reduce the utility of the program that much.
 
N

Nick Keighley

(e-mail address removed) (Kenny McCormack) writes:




Of more interest would be to ask the regs for pointers to their code so
we can verify that it is indeed compiled and used on more than their in
house MS Windows system for example.

And I mean the clique regs : not the obvious posters who do develop for
multiple platforms simultaneously.

I'm not sure which category I fall in but I maintain a C++ application
(which I can't post) that has been ported from HPUX to MS Windows.

I am aware of an application that broke when moved from one Sun
machine to another (endianess changed!).

I've weird embedded systesm where a fair amount of testing for it was
done on MS Windows some on a VAX (ok, this was a while ago!). The
weird embedded system was neither of these.

I routinely expect code to run on both Windows and Linux.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top