[comp.sys.mac.programmer] dead code, brain dead lilbrary

sdh@flash.bellcore.com (Stephen D Hawley) (02/16/90)

In article <1990Feb14.204332.24800@caen.engin.umich.edu> billkatt@mondo.engin.umich.edu (billkatt) writes:
>Think C DOES indeed remove dead code, ever since version 3.0.  It doesn't seem
>to do quite as good a job as MPW 3.0, but a good job none the less.  To
>remove dead code, just check the 'Smart Link' check box when you build your
>app/DA/whatever.  You can go out and prove it to yourself by writing a
>program which uses one small routine from the ANSI library, and building it to
>disk.  Whereas the ANSI library is 27K long, your program will come out to
>about 5 or 6K.
>
>-Steve Bollinger

Yes, it removes dead code, but the ANSI library is pretty darn stupid when
it comes to the atomicity of the libraries.

Ok, quiz question:
How many of you can write/have written atoi()?

How many lines was it for you?  A whopping 12 or 13?  Here's what Think C
4.0 uses in the library:

atoi(s)
char s;
{
	int n;

	if (sscanf(s, "%d", &n)) return(n);
	else return(0);
}

One atoi() has just destroyed me in terms of application size.  Have you seen
what sscanf() brings in with it?  Yuck.

I was so appalled by this and the general performance of the library that I
took a week and implemented a subset of the standard i/o package that
includes putc(), fputc(), getc(), fgetc(), puts(), fputs(), printf() (small
version - no float support), fprintf(), sprintf(), fopen(), fclose(), fread(),
fwrite() and more.

You can make any number of windows to printf() to.  To get input, you do an
fopen() with the magic file name "/dev/keyboard".

You get window updates for free, and it's faster than than Think C's library,
and it supports text selection and copy/paste operations.

How much memory would you sacrifice for such a beast?  10K? 15K? 27K?
Nope.  5.5K

Yes, I have a few regrets.  It should really make window objects be streams
sothat printf (actually called Wprintf()) is the same as fprintf(), and it
should have better font support, but remember I put this together in a week.

I know Think C's ANSI library has a huge amount of content, but I think some
better attention should be given to its organization so I don't buy the farm
for atoi().

Why, oh why couldn't atoi() look like this:

#define isDigit(c) ((c) >= '0' && (c) <= '9')
#define isWhite(c) ((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == '\n')
/* This is for notational convenience, so we bring in all the ctype tables.
 * Beware of side effecting c
 */
int
atoi(s)
register char *s;
{
	register int val, sign;

	/*
	 * The Berkeley UNIX manual states that atoi will read an optional
	 * number of spaces --we read an optional amount of white space,
	 * ie, space, tab, return, newline.  The byte conscious can make
	 * this just use space.
	 */
	while(isWhite(*s)) s++;

	val = 0;
	sign = 1;
	if (*s == '-') {
		sign = -1;
		++s;
	}
	while(isDigit(*s)) {
		val = 10 * val + *s - '0';
	}
	return(val * sign);
}

Steve Hawley
sdh@flash.bellcore.com
A noun's a special kind of word.
It's ev'ry name you ever heard.
I find it quite interesting,
A noun's a person place or thing.

tim@hoptoad.uucp (Tim Maroney) (02/17/90)

In article <20062@bellcore.bellcore.com> sdh@flash.UUCP (Stephen D Hawley)
writes:
>Yes, it removes dead code, but the ANSI library is pretty darn stupid when
>it comes to the atomicity of the libraries.

Actually, as I've pointed out, THINK C only removes dead code in
restricted cases --- when project files are used as libraries, and when
an entire source file is unused.  MPW Link removes all unreferenced
routines.

>Ok, quiz question:
>How many of you can write/have written atoi()?

I have.  It was a mistake.  Eventually I threw it away.  You should use
NumToString and StringToNum.  Any "atoi" you write will almost
certainly be unfriendly in international environments.  The one you
gave is.

The proper way to write atoi on the Macintosh is:

int atoi(StringPtr s) { long i; StringToNum(s, &i); return i; }
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

"Philosophy is the talk on a cereal box
 Religion is the smile on a dog" -- Edie Brickell, "What I Am"

d88-jwa@nada.kth.se (Jon Watte) (02/18/90)

In article <10294@hoptoad.uucp> tim@hoptoad.UUCP (Tim Maroney) writes:

>The proper way to write atoi on the Macintosh is:
>int atoi(StringPtr s) { long i; StringToNum(s, &i); return i; }
 ~~~                     ~~~~                        ~~~~~~~~
>Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

I can't believe this !

Any sane compiler would complain. If you reurn a long, the
function should be declared long. If you use int, you're wide
open for all kinds of incompatibilities. Int is intended only
for holding "a small integer value", and you can never assume
it can take a value higher than 32767. (Look in the standard)

h+
-- 
   ---  Stay alert !  -  Trust no one !  -  Keep your laser handy !  ---
             h+@nada.kth.se  ==  h+@proxxi.se  ==  Jon Watte
                    longer .sig available on request

ccc_ldo@waikato.ac.nz (02/19/90)

In article <2971@draken.nada.kth.se>, d88-jwa@nada.kth.se (Jon Watte)
writes:

>In article <10294@hoptoad.uucp> tim@hoptoad.UUCP (Tim Maroney) writes:

>>The proper way to write atoi on the Macintosh is:
>>int atoi(StringPtr s) { long i; StringToNum(s, &i); return i; }
> ~~~                     ~~~~                        ~~~~~~~~
>>Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

>I can't believe this !

>Any sane compiler would complain. If you reurn a long, the
>function should be declared long. If you use int, you're wide
>open for all kinds of incompatibilities. Int is intended only
>for holding "a small integer value", and you can never assume
>it can take a value higher than 32767. (Look in the standard)

The compiler converts the type of the "return" expression to
match the type returned by the function. Try changing the type
of the above "atoi" function from "int" to "short", and have a
look at the generated code, to see what I mean.

tim@hoptoad.uucp (Tim Maroney) (02/19/90)

In article <10294@hoptoad.uucp> tim@hoptoad.UUCP (Tim Maroney) writes:
>>The proper way to write atoi on the Macintosh is:
>>int atoi(StringPtr s) { long i; StringToNum(s, &i); return i; }
> ~~~                     ~~~~                        ~~~~~~~~

In article <2971@draken.nada.kth.se> d88-jwa@nada.kth.se (Jon W{tte) writes:
>Any sane compiler would complain. If you reurn a long, the
>function should be declared long. If you use int, you're wide
>open for all kinds of incompatibilities. Int is intended only
>for holding "a small integer value", and you can never assume
>it can take a value higher than 32767. (Look in the standard)

Right, but atoi is explicitly defined in the C standard as returning
an int (at least in K&R), so you can't change that.  Basically, what
you'll get is an incorrect result if you pass in a string representing
a number that's too big for an int, which is what will happen with
*any* atoi, not just this one.

My point, anyway, was not that you should do this.  You should use
StringToNum as is.  However, if you have a bunch of code lying around
that uses atoi and it's too much trouble to convert, then you should
define the routine as above -- with, if the compiler demands it, an
(int) conversion on the return statement.
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

FROM THE FOOL FILE:
"Women's wages are 56% of men's -- but that's not necessarily evidence
 of discrimination in employment."
  -- Clayton Cramer in news.groups and soc.women

d88-jwa@nada.kth.se (Jon Watte) (02/19/90)

In article <166.25e0277b@waikato.ac.nz> ccc_ldo@waikato.ac.nz writes:
>In article <2971@draken.nada.kth.se>, d88-jwa@nada.kth.se (Jon Watte)
>>In article <10294@hoptoad.uucp> tim@hoptoad.UUCP (Tim Maroney) writes:

>>>The proper way to write atoi on the Macintosh is:
>>>int atoi(StringPtr s) { long i; StringToNum(s, &i); return i; }
>> ~~~                     ~~~~                        ~~~~~~~~

>>Any sane compiler would complain. If you reurn a long, the

I meant should. English is not my native language.

>>function should be declared long. If you use int, you're wide
>>open for all kinds of incompatibilities. Int is intended only

>The compiler converts the type of the "return" expression to
>match the type returned by the function. Try changing the type
>of the above "atoi" function from "int" to "short", and have a
>look at the generated code, to see what I mean.

Try changing half of the longs you use to shorts, randomly,
and see how long your program copes. One minute ? Two minutes ?

assigning a long to an inte is _never_ a good practise -
and in this case, it happens to work on MPW C 3 but not earlier
or other Mac compilers. (Work == give the desired effect)

In general, one should never use ints other than as small
indicies in loops... Anyone think of another use for ints ?

h+
-- 
   ---  Stay alert !  -  Trust no one !  -  Keep your laser handy !  ---
             h+@nada.kth.se  ==  h+@proxxi.se  ==  Jon Watte
                    longer .sig available on request

ech@cbnewsk.ATT.COM (ned.horvath) (02/20/90)

In article <10294@hoptoad.uucp> tim@hoptoad.UUCP (Tim Maroney) writes:
 
>The proper way to write atoi on the Macintosh is:
>int atoi(StringPtr s) { long i; StringToNum(s, &i); return i; }
 ~~~                     ~~~~                        ~~~~~~~~
>Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com
 
From article <2971@draken.nada.kth.se>, by d88-jwa@nada.kth.se (Jon Watte):
> I can't believe this !
> 
> Any sane compiler would complain. If you reurn a long, the
> function should be declared long. If you use int, you're wide
> open for all kinds of incompatibilities...

Sorry, Tim is absolutely right.  The Portable C Library standard defines
atoi as returning int (not long, not short).  StringToNum returns a long.
int and long are always compatible, so a compiler might warn, but not fail,
when passed Tim's routine.

Life isn't always so simple...

=Ned Horvath=

sdh@flash.bellcore.com (Stephen D Hawley) (02/21/90)

I write:
*Ok, quiz question:
*How many of you can write/have written atoi()?
Tim Writes:
>I have.  It was a mistake.  Eventually I threw it away.  You should use
>NumToString and StringToNum.  Any "atoi" you write will almost
>certainly be unfriendly in international environments.  The one you
>gave is.
>
>The proper way to write atoi on the Macintosh is:
>
>int atoi(StringPtr s) { long i; StringToNum(s, &i); return i; }


Agreed, this is the best way to write it for a Macintosh-specific
application.  This, however, does not apply if you are porting *from*
a UNIX environment.  I wrote my atoi() to be strictly compatible with the
Berkeley UNIX manual, but that is not the nit I was picking.

My point was not: "who can write the shortest atoi()?",
but the more important question: "when will Think C's libraries be put
in a reasonable order?"  Since Think's atoi() is defined using sscanf(),
you bring most of the world with you no matter how smart the linker is.

atoi() is not, by far, the only culprit of this.  Think's ANSI library should
have a far greater atomicity than it does.  Applications shouldn't HAVE to
be several extra K long because of this.  "Sure", one might say, "memory and
storage are cheap.  What's a few K among friends?"  It means a lot to me.  I
consider programmer a craft.  Think's ANSI library is sloppy craftsbeingship.

Consider the following program:

#include <stdio.h>

main()
{
	int i = atoi("12345");
}

If you build an application from this you get the following sizes:
Library				App. Size in bytes	Library Size in bytes
ANSI-small			7,890			11,818
ANSI				20,978			27,972
my atoi()			1,272			122

I don't care about atoi(), I care about the luggage I have to haul around.

Steve Hawley
sdh@flash.bellcore.com
A noun's a special kind of word.
It's ev'ry name you ever heard.
I find it quite interesting,
A noun's a person place or thing.