Re: help needed please!

From: The Real OS/2 Guy (os2guy_at_pc-rosenau.de)
Date: 01/19/04


Date: Mon, 19 Jan 2004 09:56:44 +0000 (UTC)

On Sun, 18 Jan 2004 14:16:41 UTC, "Peter Nilsson" <airia@acay.com.au>
wrote:

> "The Real OS/2 Guy" <os2guy@pc-rosenau.de> wrote in message
> news:wmzsGguTDN6N-pn2-6xUmS86KvrDj@moon...
> > On Sat, 17 Jan 2004 11:17:52 UTC, Buck Rogers <who@cares.com.au>
> > wrote:
> ...
> > > #include <stdio.h>
> > > #include <stdlib.h>
> > >
> > > int menu( void );
> > >
> > > int main( void )
> > > {
> > > int option;
> > >
> > > while(1) {
> >
> > This while is NOT wrong! But some compilers like to give you a warning
> > here that the test is against a constant. Avioding this warning is
> > simple:
>
> And unnecessary. [Just turn off the warning or get a better compiler... ;-]

Never! Each warning a compiler can give you is important when you not
aware of. A condition that evaluates always true is often senseless
and points to a programming error.
A loop without condition is in contrast to that normal.

> > replace the while with
> >
> > for (;;) {
> >
> > The result is the same - but the compiler is quite still.
>
> Not if someone writes a compiler with warnings like...
>
> warning: no expression used in for loop

This is senseless - always.
 
> Warnings (and the ability to turn them off) is a QoI issue.
>
> > Somebody like to have a macro for this:
> >
> > #define FOREVER for (;;)
> >
> > and then instead writing the empty loop like
> > FOREVER [
> > but it is easy to trick out onesef because one tends to append the
> > semicolon to the macro - and as that is not a syntax error it produces
> > some unwanted code.
>
> It seems to lose something in translation, but it sounds like a good reason
> for not defining such a macro. ;)
>
> > > option = menu();
> > > switch(option) {
> > > case 1:
> > > system("dir");
> > > break;
> >
> > use continue istead of break; break breaks the switsh block. continue
> > iterates the while and shows the reader that your current run is
> > clearly done.
>
> I don't think that's a good thing to do in general. If the programmer later
> wants to add some housekeeping after the the switch statement, then they've
> got to replace all the continue statements [back to breaks which would have
> worked just fine in the initial instance.]

No, but you may use flages to handle flags to handle flags when you
are unable to work out a clean design. Don't hack around and you'll
have always functions with a clean design, avoiding gotos, flags and
flags you don't need. Learn how to use continue and you'll save flags
have clean and short code.

Whenever an action is done 'contimue' is good to flag that. 'break'
shows that you're halfway done, but something left over for common
actions.

'exit()' is good for emergency breakout - but never for break on data
fault. A well designed program does never use exit except for an point
whereas nothing else makes sense.
 
> ...
> > > default:
> > > puts("Not a valid option, try again");
> >
> > another continue here makes cleear that you will run the next while.
> >
> > > }
> >
> > Now, whenever you falls through the switch block you knows your while
> > should break, so
> >
> > break;
> >
> > lets you reach the return and the compiler will be happy.
> >
> > > }
>
> That looks like goto style spagetti code to me!

No, it's clear: continue shows up that anything to do is done, next
loop has to run. Break from switch shows that there is something left
to do. And in this case the only that can left over is to break the
whole loop. spaghetti code looks absolutely different. It were easy to
use goto but goto will break ever the flow - and there is no need to
break the flow. Again, learn what continue does for you. It helps you
to document the data flow!
 
> > > return 0;
> > > }
>
> ...
> > > int main( void )
> > > {
> > > int a, b;
> > > char c;
> > >
> > > puts("Enter an integer");
> >
> > Depending on your terminal nothing is shown yet.
>
> Yes, you will need a working switched on monitor to see the prompt! <g>

[ ] You knows the difference between unbuffered, line buffered and
block buffered devices.
 
> > This is because
> > stdout is line bufferd and until one or both of the following cases is
> > not fullifyied nothing is send to the stream: either line is full or
> > newline is given.
> >
> > fflush(stdout);
> >
> > resolves that. This forces the stream to send the buffer to the device
> > immediately.
>
>
> The puts() call appends a \n to the output [though fputs() doesn't.] If
> stdout is fully buffered, then the user isn't likely to see the prompt with
> or without the fflush. So the fflush() is redundant in this case.
>
> > > scanf("%d", &a);
> >
> > scanf is errornous! You should avoid it. O.k., here is buffer overflow
> > no problem, but when you use scanf with other format string it is easy
> > to fall into that trap.
> >
> > scanf is not designed to interact with keyboard or other other
> > untrusted devices.
>
> Huh?

Give
d o n ' t t y p e t ex t wh en y h a ve t
o
t
y p
e
a n
um
er
instead a number and try to catch that. Users are crazy alays. You
have more work to catch typing errors than to work with regular input.

Writing an own function to receive exactly that you awaits from the
stream makes it much easier to handle the crap a user gives you as you
ever can have with the old design (f)scanf() brings. Reading something
in only to copy it again to copy it again to scan it is waste of
resources.
 
>
> Why not just use *u ?

A leftover from the old days where compilers were not so good in
optimising and code generation as today and the time difference
between indirect addressing as in modifying a variable a pointer
points to was really slow because the mashine was unable to do it
other than to read to a register modify that register and write back.
Direct register manipulation was in factor 10 to 100 more quick!

> > int i = 0;
> >
> > while ((c = getc(in) != EOF) {
> > if (c == '\n') break; /* newline found */
>
> Redundant test as '\n' is not a digit.

O.k., yes - but a bit documentation that distinguishes betwen unwanted
and wanted chars.
 
> > if (isdigit(c)) {
>
> if (isdigit((unsigned char) c))
>
> > rc *= 10;
> > rc += c - '0';
>
>
> And what happens if and when the int overflows?

Have you ever done this test in a real program? You can do it anyway
as you can test if the number of digits should reflect it.
 
> Your method does nothing to detect the case where an unsigned integer
> overflow has occured. That said, 100% bullet proof methods for integer input
> are surprisingly non trivial.

It is trivial - but costs more code when you have the real need to
dedect it immediately.

Save the old vale. Add and compare with the old value. Whenever the
old value is lower as the new one you have had an overflow in unsigned
arithmetic. Simple.

Does you really check each and any arithmetic operation for overflow?
I don't think so.

Here it is easy to let the user of the function do it when he feels
the need. That is one of the points why the function returns the
number of digits readed and not only the converted number.

-- 
Tschau/Bye
Herbert
Visit http://www.ecomstation.de the home of german eComStation


Relevant Pages

  • Re: [PATCH 3/3] Enforce "unsigned long flags;" when spinlocking
    ... something different from "unsigned long flags;". ... This is a pretty ugly-looking patch. ... I want build system, compiler, headers etc to do everything against ... sparse spits warning ...
    (Linux-Kernel)
  • -W flag to /opt/SUNWspro/bin/CC
    ... This isn't exactly about Solaris but rather the Sun compiler suite. ... Every modern compiler I know supports a -W meta-flag for passing flags through to interior tools such as ld, as, cpp, etc. So I was shocked to find that apparently the Sun Studio C++ compiler doesn't. ... CC actually does pass unrecognized flags to the linker but it spits out a warning each time. ...
    (comp.unix.solaris)
  • Re: Why INFINITE loop in a thread occupy so much CPU time??
    ... With the attendant warning about the constant expression. ... This is a common programming technique. ... Good programming practice would consist of using the compiler at ... One can write 'bool' in C++ but not C. ...
    (microsoft.public.vc.mfc)
  • Re: Overloading abstract methods
    ... I'm calling this abstract class ResumeWriter. ... > use of in each subclass is up to you. ... >> However, if I do that, I get compiler warnings that the parameters for ... Disable that warning. ...
    (comp.lang.java.programmer)
  • Re: Why does this work?
    ... The compiler is able to tell the difference between the two by the context in which the word "color" is used. ... The point is that the compiler reads the original code as attempting to access a shared member of an instance. ... That's why the compiler is warning the programmer that it's not going to do what was coded. ...
    (microsoft.public.dotnet.languages.vb)