🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.c.moderated
Article #2124

Re: Evil C Contests

#2124
From: J. Kanze
Date: Fri, 01 Mar 1996 15:32
101 lines
3724 bytes
In article <4gj0rk$lqj@solutions.solon.com> sl14@crux1.cit.cornell.edu
(S. Lee) writes:

|> In article <4ghnp2$djn@solutions.solon.com>,
|> Sean 'Captain Napalm' Conner <spc@gate.net> wrote:
|> >
|> >  How about a contest to "Spot the Bug/Portibility Problem"?  For example, why
|> >is the following program buggy (and possibly not portable)?
|> >
|> >#include <stdio.h>
|> >#include <limits.h>
|> >#include <string.h>
|> >#include <stdlib.h>
|> >#include <ctype.h>
|> >
|> >int main(void)
|> >{
|> >  long counts[CHAR_MAX];
|> >  int  c;
|> >  int  i;
|> >
|> >  memset(counts,0,sizeof(counts));
|> >  while((c = getchar()) != EOF)
|> >  {
|> >    counts[c]++;
|> >  }

|> Won't work if char is signed.  The array size is too small and all these
|> nastiness with negative array indices.  I don't know how to classify this,
|> it is definitely portability-related, but I'd say this is a bug.

Two comments:

1. Even if char is unsigned, the array size is too small.  On a typical
8 bit machine, for example, 0xff is a legal character, which will index
one beyond the end of the array.  (In ISO 8859-1, 0xff is a y-umlaut.
The letter occurs in Finnish, I think.  So you have a program which
seems to work, but mysteriously fails if the input is in Finnish. A case
which, I'll bet, you didn't think to test before releasing the program
to the customers:-).)

The correct definition for most machines (but see below) will be:

	long counts[ UCHAR_MAX + 1 ];

2. There is no problem of negative indexes, even if char is signed.
getchar always returns a positive value (in the range 0...UCHAR_MAX
inclusive), or EOF.  And the author didn't make the biginner's mistake
of assigning it to a char.

|> >  for (i = 0 ; i < CHAR_MAX ; i++)

|> You're leaving out the last element here even if char is unsigned.

|> >  {
|> >    if (isprint(i))
|> >      printf("%c:",i);
|> >    else
|> >      printf("%d:",i);
|> >    printf("\t50l\n",counts[i]);

|> And here you have a typo.

|> This is fun, took me two false start to spot the real bad thing.
|> How to fix it?  Hmm... the first one is tricky.  I guess 

|> long counts[UCHAR_MAX];
|> unsigned char uc;

|> and

|> while ((c = getchar()) != EOF)
|> {
|>   uc = c;
|>   counts[uc]++;
|> }

|> might work...

The real portability problem is what will happen on a machine where
sizeof( int ) == sizeof( char ).  And if INT_MAX == CHAR_MAX.  To tell
the truth, I'm not even sure what the standard says about this: getchar
returns an int in the range of 0...UCHAR_MAX, but UCHAR_MAX won't fit in
an int.

No matter what the standard says, getting the end condition of the
output loop right is going to be tricky, since UCHAR_MAX + 1 == 0.
Thus:

	for ( i = 0 ; i < UCHAR_MAX + 1 ; i ++ )

doesn't execute the loop at all, and

	for ( i = 0 ; i <= UCHAR_MAX ; i ++ )

is an infinite loop.
-- 
James Kanze           (+33) 88 14 49 00          email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils, études et réalisations en logiciel orienté objet --
              -- A la recherche d'une activité dans une region francophone
Technical Details
Message-ID: <4h75a2$4l6@solutions.solon.com>
Path: arc1-ca.pugleaf.net!solon.com!not-for-mail
References: <4fu7pp$94q@solutions.solon.com> <4g55jo$b44@solutions.solon.com> <4gfaki$1uc@solutions.solon.com> <4ghnp2$djn@solutions.solon.com>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!solon.com!not-for-mail
From: kanze@gabi-soft.fr (J. Kanze)
Newsgroups: comp.lang.c.moderated
Subject: Re: Evil C Contests
Date: 1 Mar 1996 09:32:18 -0600
Organization: GABI Software, Sarl.
Sender: clc@solutions.solon.com
Approved: clc@solutions.solon.com
Message-ID: <4h75a2$4l6@solutions.solon.com>
References: <4fu7pp$94q@solutions.solon.com> <4g55jo$b44@solutions.solon.com>
 <4gfaki$1uc@solutions.solon.com> <4ghnp2$djn@solutions.solon.com>
NNTP-Posting-Host: solutions.solon.com