Re: worst.c - foolishness

From: Jarno A Wuolijoki (jwuolijo_at_cs.Helsinki.FI)
Date: 01/14/04


Date: Wed, 14 Jan 2004 04:40:56 +0200

On Tue, 13 Jan 2004, Arthur J. O'Dwyer wrote:

> > ITYM
> > char* fmt = "%d, %l", c;
>
> My mistake. ;-)
>
> > It would be better though if c was somehow used as if it were a
> > char* instead. Otherwise it just adds up to obfuscation.
>
> I think you'd have trouble avoiding a compiler warning in that case.

Not really. Strings are usually handled through functions and we're
not including the important stuff to get complaints. (though in this
respect gcc is sometimes one of the "smart compilers" with its built in
checking for variadic functions)

> > > > unsigned int z;
> > > > while (!feof()) {
> > > Surely you meant
> > > while (!feof(stdin)) {
> > > This will avoid the warnings from those so-called "smarter" compilers. :)
> >
> > Dunno, it's one bug less if you ignore the misdefinition..
>
> How so? My change merely replaces "undefined behavior upon calling
> unprototyped function with wrong arguments" (which Chuck already had
> elsewhere) with "undefined behavior upon passing NULL to feof()". Plus,
> my bug is much subtler.

Ok. Just that the bug's on another line, here we just see the results;)

> Doesn't that remove the bug, though? scanf("%d%s", z, &c) will
> most likely try to store a string in the memory pointed to by &c
> (invoking undefined behavior on buffer overrun); but the bug I was
> trying to introduce there was that
>
> scanf("%d", &foo);
> gets(bar);
>
> will store a number in 'foo', and then, assuming the user has pressed
> 'Return' to end that line of input, will proceed to read and discard
> a single newline.

Ouch. I completely unrealized the intent there..

> OTOH, the gets() doesn't actually have a bug then;
> it will store only a single '\0', won't it? So maybe keep that gets(),
> but introduce the
>
> scanf("%d", &foo);
> fgets(&c, sizeof &c, stdin);
>
> bug(s) elsewhere in the code. [Bugs include lack of prototype for
> fgets, causing undefined behavior when passing literal 0 as third
> argument; mis#defined 'stdin' that causes the literal 0 in the first
> place; passing NULL to fgets in the first place; buffer overflow;
> abuse of the 'sizeof' operator; lack of error-checking on scanf;
> and the above-mentioned mishandling of possible newline characters
> in the input.]

You're approaching the bubble sort:

sizeof abuse, off by 2 error had it worked, unsigned gotcha,
z vs zz, extra ;, dangerous comparision, sequence point problem on
swap, zeroing data when &__a==&__b, invasion of implementation
namespace, possible trap when performing binary stuff on chars
and modification of a string literal.

> > while (feof()==EOF) {
> I think the use of == for != is too blatant a mistake. But it
> occurs to me that we haven't misused De Morgan's Rule yet; we need
> something along the lines of

Nah. It just shows why you shouldn't write bad code in the first place.
Mistakes invite more mistakes. It was a genuine;)

> while (feof()!=EOF || c=(int)getchar() != EOF) {

Subtle.. I don't like the doublecheck for eof though. Checking first
for eof and then for errors makes it look better thought out.

 
> [I like my cast better than yours. Yours is only designed to
> placate the compiler, AFAICT; mine has the "good" intention of
> making sure the result of getchar() is wide enough to hold 'EOF'
> before assignment to c. ;-) ]

So it's
"hideous practice that lets you shoot your own foot quietly"
against
"terrible misunderstanding of how the language works" ;)

> Finally, it occurs to me that we haven't abused 'goto' yet, nor
> attempted to 'switch' on some inappropriate type. Nor even inserted
> anywhere an
> if (strfmt == "foo")
> ;-)

I like !strcmp(strfmt, "foo")==0 too (for having actually seen it), but
maybe it's too obvious..



Relevant Pages

  • Re: worst.c - foolishness
    ... Note the subtle change ... it's one bug less if you ignore the misdefinition.. ... elsewhere) with "undefined behavior upon passing NULL to feof". ... will store a number in 'foo', and then, assuming the user has pressed ...
    (comp.lang.c)
  • Re: Opinions on this code please guys....
    ... to see if the string writes off the end of the buffer. ... there's no check for error (or even EOF) which is quite ... This is allso undefined behavior and stupid. ... Even the above is horrendously ineffiient and stupid. ...
    (comp.lang.cpp)
  • Re: Buffer overflows and asctime()
    ... legalese tend to get lost in their word mazes and loose ... the technical knowledge that should be the basis of ... what is a BUG and how to fix it. ... This call to strcpyinvokes undefined behavior. ...
    (comp.std.c)
  • Re: lcc-win32
    ... > timeptr produce undefined behavior in the sample algorithm (for ... > I think that this was the wrong answer to give to a bug report. ... If you wish you can write a supervisory function to do the error ...
    (comp.lang.c)
  • Re: Realloc destroys?
    ... i can store way more than that. ... >>> to work though you might corrupt some other memory. ... > * This invokes undefined behavior by writing past the end ... > As soon as I assigned a value to ptr, I invoked undefined behavior, ...
    (comp.lang.c)

Loading