[comp.sys.sun] Why is sprintf ifdef-ed out of <stdio.h>?

bob@omni.com (Bob Weissman) (07/21/89)

/usr/include/stdio.h has the declaration of sprintf() ifdef-ed out:

    /*      @(#)stdio.h 1.12 88/02/07 SMI; from UCB 1.4 06/30/83    */
    ...
    #ifdef vax
    char    *sprintf();             /* too painful to do right */
    #endif

Why is this?  It implies programs which use it have to declare it
themselves.

And what is so painful about the ifdef-ed out declaration, anyway?

Bob Weissman
Domainish: bob@omni.com
UUCPish:   ...!{amdahl,apple,pyramid,sgi,tekbspa,uunet}!koosh!bob

chris@mimsy.umd.edu (Chris Torek) (07/28/89)

bob@omni.com (Bob Weissman) asks why there is an `#ifdef vax' around the
`char *sprintf()' declaration in stdio.h.

The reason is that sprintf() is supposed to return an int value, namely
the number of characters printed, but it was `too painful' to fix this for
4.2 and 4.3 BSD, so it was left *wrong* in the BSD VAX systems and made
correct in SunOS.

Why the `#ifdef vax' ... `#endif' lines were never removed from the Sun
stdio.h I cannot answer.  Note that sprintf() has been fixed in
4.3BSD-tahoe.

In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

trinkle@cs.purdue.edu (08/11/89)

bob@omni.com (Bob Weissman) asks why there is an `#ifdef vax' around the
`char *sprintf()' declaration in stdio.h.

and chris@mimsy.umd.edu (Chris Torek) replies:
The reason is that sprintf() is supposed to return an int value, namely
the number of characters printed, but it was `too painful' to fix this for
4.2 and 4.3 BSD, so it was left *wrong* in the BSD VAX systems and made
correct in SunOS.

Actually, it depends on what was compiled into your C library.  There are
two source files for the SunOS 4.0 sprintf() routine.  One returns the
char * consistent with 4.2 BSD and the other returns an int (the character
count).  The bad thing is that Sun's /usr/lib/lint/llib-lc says that
sprintf() returns a char *.  Clearly, this is not always true and it does
not agree with /usr/include/stdio.h.

But then who really uses lint anyway -- clearly not Sun.  When checking
rpc.yppasswdd.c (we added some features and fixed a security whole) I saw
things like calls to socket() and bind() with too many arguments,
redefining a standard library routine (rresvport()), and much more.  This
is just one example out of hundreds, but something that is clearly all Sun
(not borrowed from BSD).  These are the poeple that are claiming to have
an "almost" C2 secure system?!

Script started on Fri Aug 11 08:55:04 1989
bors 6: lint /usr/src/sun4.0/usr.etc/rpc.yppasswdd.c.orig
lint: Warning: File with unknown suffix (/usr/src/sun4.0/usr.etc/rpc.yppasswdd.c.orig) passed to lint1
/usr/src/sun4.0/usr.etc/rpc.yppasswdd.c.orig(149): warning: fp unused in function changepasswd
/usr/src/sun4.0/usr.etc/rpc.yppasswdd.c.orig(144): warning: argument rqstp unused in function changepasswd
getpwnam multiply declared      /usr/src/sun4.0/usr.etc/rpc.yppasswdd.c.orig(371)  ::  llib-lc(339)
rresvport: variable # of args.  /usr/src/sun4.0/usr.etc/rpc.yppasswdd.c.orig(333)  ::  llib-lc(432)
rresvport multiply declared     /usr/src/sun4.0/usr.etc/rpc.yppasswdd.c.orig(333)  ::  llib-lc(432)
pmap_unset, arg. 1 used inconsistently  llib-lc(622)  ::  /usr/src/sun4.0/usr.etc/rpc.yppasswdd.c.orig(99)
pmap_unset, arg. 2 used inconsistently  llib-lc(622)  ::  /usr/src/sun4.0/usr.etc/rpc.yppasswdd.c.orig(99)
svc_register, arg. 2 used inconsistently        llib-lc(627)  ::  /usr/src/sun4.0/usr.etc/rpc.yppasswdd.c.orig(101)
svc_register, arg. 3 used inconsistently        llib-lc(627)  ::  /usr/src/sun4.0/usr.etc/rpc.yppasswdd.c.orig(101)
svc_register, arg. 4 used inconsistently        llib-lc(627)  ::  /usr/src/sun4.0/usr.etc/rpc.yppasswdd.c.orig(101)
svc_sendreply, arg. 3 used inconsistently       llib-lc(629)  ::  /usr/src/sun4.0/usr.etc/rpc.yppasswdd.c.orig(133)
bzero, arg. 1 used inconsistently       llib-lc(227)  ::  /usr/src/sun4.0/usr.etc/rpc.yppasswdd.c.orig(163)
wait3, arg. 3 used inconsistently       llib-lc(196)  ::  /usr/src/sun4.0/usr.etc/rpc.yppasswdd.c.orig(171)
strcmp, arg. 1 used inconsistently      llib-lc(471)  ::  /usr/src/sun4.0/usr.etc/rpc.yppasswdd.c.orig(196)
crypt value used inconsistently llib-lc(233)  ::  /usr/src/sun4.0/usr.etc/rpc.yppasswdd.c.orig(196)
strcmp, arg. 1 used inconsistently      llib-lc(471)  ::  /usr/src/sun4.0/usr.etc/rpc.yppasswdd.c.orig(216)
crypt value used inconsistently llib-lc(233)  ::  /usr/src/sun4.0/usr.etc/rpc.yppasswdd.c.orig(216)
svc_sendreply, arg. 3 used inconsistently       llib-lc(629)  ::  /usr/src/sun4.0/usr.etc/rpc.yppasswdd.c.orig(328)
socket: variable # of args.     llib-lc(178)  ::  /usr/src/sun4.0/usr.etc/rpc.yppasswdd.c.orig(339)
bind: variable # of args.       llib-lc(55)  ::  /usr/src/sun4.0/usr.etc/rpc.yppasswdd.c.orig(344)
bind, arg. 2 used inconsistently        llib-lc(55)  ::  /usr/src/sun4.0/usr.etc/rpc.yppasswdd.c.orig(344)
crypt value declared inconsistently     llib-lc(233)  ::  /usr/src/sun4.0/usr.etc/rpc.yppasswdd.c.orig(216)
strcpy value declared inconsistently    llib-lc(472)  ::  /usr/src/sun4.0/usr.etc/rpc.yppasswdd.c.orig(310)
strcat value declared inconsistently    llib-lc(469)  ::  /usr/src/sun4.0/usr.etc/rpc.yppasswdd.c.orig(313)
fprintf returns value which is always ignored
pmap_unset returns value which is always ignored
close returns value which is always ignored
ioctl returns value which is always ignored
signal returns value which is sometimes ignored
fclose returns value which is always ignored
unlink returns value which is always ignored
strcpy returns value which is always ignored
strcat returns value which is always ignored
system returns value which is always ignored
bors 7: 
script done on Fri Aug 11 08:56:57 1989

guy@uunet.uu.net (Guy Harris) (08/16/89)

>The reason is that sprintf() is supposed to return an int value, namely
>the number of characters printed, but it was `too painful' to fix this for
>4.2 and 4.3 BSD, so it was left *wrong* in the BSD VAX systems and made
>correct in SunOS.

More correctly, an attempt was made to make it correct in SunOS 2.0 or so,
but it was, well, too painful, so it was changed back.  ("printf" and
"fprintf" were changed in 2.0, though, so that they return the number of
characters printed.)

(Actually, in V7 "sprintf" returned its first argument, although as I
remember this was undocumented; AT&T changed it in S3, but as I remember
some bit of the S3 "sccs" command still depended on the old behavior....
ANSI C specifies the "return the number of characters generated" behavior,
so over time the old behavior will, with any luck, die out.)

rbj@dsys.ncsl.nist.gov (Root Boy Jim) (08/24/89)

? From:    Chris Torek <chris@mimsy.umd.edu>

? bob@omni.com (Bob Weissman) asks why there is an `#ifdef vax' around the
? `char *sprintf()' declaration in stdio.h.

? The reason is that sprintf() is supposed to return an int value, namely
? the number of characters printed, but it was `too painful' to fix this for
? 4.2 and 4.3 BSD, so it was left *wrong* in the BSD VAX systems and made
? correct in SunOS.

Made correct in which version? I ran a test prog under 3.5 and it returns
the first arg. My Version 4 (probably 4.0) manual sez that it still
returns char *. I have no access to a running 4.x system.

? Why the `#ifdef vax' ... `#endif' lines were never removed from the Sun
? stdio.h I cannot answer.  Note that sprintf() has been fixed in
? 4.3BSD-tahoe.

Perhaps your local SunOS/BSD hybrid has the Tahoe sprintf?

? In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
? Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

	Root Boy Jim
	Have GNU, Will Travel.