[comp.sys.sgi] Is this a lint bug?

butler@BRL.MIL ("Lee A. Butler") (12/15/90)

Can someone please explain why lint isn't happy with the following program?
Am I really supposed to cast *loc to be "(signed char)*loc" which seems to
be what is necessary?  I thought that "signed char" was strictly an ANSI C
construct.

1 >cat test.c
#include <stdio.h>

main()
{
        char *loc;
        char cp[64];

        loc = "hello world";
        
        (void)sprintf(cp, "%s=\"%c\"\n", "the first character", *loc);
        (void)printf("%s", cp);

        return(0);
}
2 >lint test.c

test.c
==============
Warning: (10)  sprintf: (char) format, (unsigned char) arg (arg 4)
3 >cc -o test test.c
4 >test
the first character="h"

For Those who want gritty details about environment:

4 >versions
I = Installed, R = Removed

  Name                  Date      Description
I  dev                  90/09/14  4D1-3.3 Development System
I  dwb                  89/11/20  DWB Opt PD, S4-DWB-3.2, 808-0012-010
I  eoe1                 90/09/14  4D1-3.3 Execution Only Environment (part
                                    1)
I  eoe2                 90/09/14  4D1-3.3 Execution Only Environment (part
                                    2)
I  ftn                  90/09/14  4D1-3.3 Fortran Option
I  maint1                         (unknown product)
I  maint1               90/09/14  Maint1 Product 4D1-3.3.1
I  nfs                  90/09/14  4D1-3.3 Network File System
I  pfa                  90/09/14  Power Fortran Accelerator
R  slip                 90/02/09  IRIS Slip Product
R  vis                  90/01/12  Personal Visualizer PD, 808-0160-001
I  vtools               89/11/17  IRIS Visual Tools PD, 808-0167-001
5 >hinv
8 25 MHZ IP7 Processors
FPU: MIPS R2010A/R3010 VLSI Floating Point Chip Revision: 2.0
CPU: MIPS R2000A/R3000 Processor Chip Revision: 2.0
Data cache size: 64 Kbytes
Instruction cache size: 64 Kbytes
Main memory size: 128 Mbytes
Xylogics 1/2 inch tape controller 0 ctlr type: 772 firmware: 2.5
8 25 MHZ IP7 Processors
FPU: MIPS R2010A/R3010 VLSI Floating Point Chip Revision: 2.0
CPU: MIPS R2000A/R3000 Processor Chip Revision: 2.0
Data cache size: 64 Kbytes
Instruction cache size: 64 Kbytes
Main memory size: 128 Mbytes
Xylogics 1/2 inch tape controller 0 ctlr type: 772 firmware: 2.5
ENP-10 Ethernet controller 1, firmware version 4 (SGI)
Integral Ethernet controller: Version 2
Xylogics 754 4-drive SMD disk controller 0: Firmware version 2.7.0
SMD Disk drive: unit 3 on Xylogics controller 0
SMD Disk drive: unit 2 on Xylogics controller 0
SMD Disk drive: unit 1 on Xylogics controller 0
SMD Disk drive: unit 0 on Xylogics controller 0
Xylogics 754 4-drive SMD disk controller 1: Firmware version 2.7.0
SMD Disk drive: unit 3 on Xylogics controller 1
SMD Disk drive: unit 2 on Xylogics controller 1
SMD Disk drive: unit 1 on Xylogics controller 1
SMD Disk drive: unit 0 on Xylogics controller 1
Integral SCSI controller 0: Version WD33C93
Disk drive: unit 1 on SCSI controller 0
                                      

Lee A. Butler
SLCBR-VL-V					Internet: butler@brl.mil
Ballistic Research Laboratory			   Phone: (301) 278-9200
Aberdeen Proving Grounds, MD 21005-5066

butler@BRL.MIL ("Lee A. Butler") (12/15/90)

Based upon some early returns, I can see that I did not communicate well
enough in my first posting.  Allow me to attempt a more thorough description.
The lines in "test.c" which have the "/* warn */" comments generate warnings
from lint.  I don't understand why, since in each case, a value of type "char"
is what is provided.  

Script started on Fri Dec 14 19:58:03 1990
1 >cat test.c
#include <stdio.h>
char *str = "the first character";
main()
{
        char *loc = "hello world";
        char cp[64];
        
        (void)sprintf(cp, "%s=\"%c\"\n", str, *loc);            /* warn */
        (void)sprintf(cp, "%s=\"%c\"\n", str, (char)*loc);      /* warn */
        (void)sprintf(cp, "%s=\"%c\"\n", str, *((char *)loc));  /* warn */

        (void)sprintf(cp, "%s=\"%c\"\n", str, (signed char)*loc);    /* ok */
        (void)sprintf(cp, "%s=\"%c\"\n", str, *((signed char*)loc)); /* ok */

        (void)printf("%s", cp);

        return(0);
}
2 >lint test.c

test.c
==============
Warning: (8)  sprintf: (char) format, (unsigned char) arg (arg 4)
Warning: (9)  sprintf: (char) format, (unsigned char) arg (arg 4)
Warning: (10)  sprintf: (char) format, (unsigned char) arg (arg 4)
3 >exit
exit

script done on Fri Dec 14 19:59:06 1990

script done on Fri Dec 14 19:59:07 1990

While I am aware that on various architectures, variables of type "char"
behave as either "unsigned char" or "signed char", I would expect such
behavior to be consistent.  I would also expect lint to be unconcerned 
with architecture specifics such as this.  Lint should only be concerned
with a variable's declared type.  A variable of type "char" should be portably
passed to sprintf for a "%c" format irrespective of whether the local
architecture treats "char" variables as signed (implying sign extension when
passed to sprintf) or unsigned (no sign extension).

Furthermore, I believe that the "signed" keyword is an ANSI C construct.
Thus, while the type "char" may (or may not) behave as a signed char, it is
unreasonable for lint to expect me to cast all of my "char" variables as
"signed char" for use with sprintf and friends.  The "signed" keyword is an
"available" but not "required" keyword in ANSI C programs.

Lee A. Butler
SLCBR-VL-V					Internet: butler@brl.mil
Ballistic Research Laboratory			   Phone: (301) 278-9200
Aberdeen Proving Grounds, MD 21005-5066

kcables@RELAY.NSWC.NAVY.MIL (12/18/90)

Lee,
	I'm not sure why, but I've run into problems using a filename
called 'test.c'.  Try renaming it.  I even wrote a note to myself not
to use 'test.c', because I kept doing it when I was writing test programs
and I'd get funny I/O errors.  Just a stab in the dark.

Kathryn Cables
kcables@relay.nswc.navy.mil

thant@horus.esd.sgi.com (Thant Tessman) (12/20/90)

In article <9012180823.aa06610@VGR.BRL.MIL>, kcables@RELAY.NSWC.NAVY.MIL
writes:
|> Lee,
|> 	I'm not sure why, but I've run into problems using a filename
|> called 'test.c'.  Try renaming it.  I even wrote a note to myself not
|> to use 'test.c', because I kept doing it when I was writing test programs
|> and I'd get funny I/O errors.  Just a stab in the dark.
|> 
|> Kathryn Cables
|> kcables@relay.nswc.navy.mil

This bites me all the time.  'test' is a unix command.
See test(1).

thant