ANSI C questions

jlevy at teknowledge-vaxc.UUCP jlevy at teknowledge-vaxc.UUCP
Wed Jul 13 10:39:25 AEST 1988


I am porting some old "K&R" C to a new compiler which claims to be as close 
to ANSI draft standard as possible.  This has generated some questions:

1. Is this code legal:

     #include <string.h>
     static char *foo = "" ;
     char bar[20] ;
     strncpy(bar,foo,strlen(foo)) ;
    
     The compiler that I have treats a zero third argument to strncpy as a
     run time error, and aborts the program.  Does the standard permit this
     behavior? 

2. Is this code legal:

    void func(n,a,p) int n ; int a[] ; int (*p)() ;
    {
        int r ;

        switch (n) {
	  case 0:
		(*p)(r) ;           break ;
	  case 1:
		(*p)(r,a[0]) ;      break ;    /* compiler error here */
	  case 2:
		(*p)(r,a[0],a[1]) ; break ;    /* compiler error here */
	  default:
	    /* error message */
	}
    }
    
    The compiler generates errors (function used with wrong number of
    arguments) after the two lines marked.  The programmer supporting 
    the compiler claims that this is legal.  His argument is that since 
    there is no functional prototype in scope for p, the compiler can 
    take the first time p is used and generate a prototype for p, 
    comparing all future uses of p with that prototype.  He refers to
    this as the "Miranda Rule", and claims it is in the Draft standard,
    or the Rationale.  I can not find it.  

    I hold that since there is not a prototype in scope for p, the compiler
    must treat it as a function taking a constant number of arguments [1].
    Since it is a variable, each time it is used it should be treated
    as different function (since it often will be a different function).

3. Is this code legal:

    long big = 600000L ;
    int small ;

    small = (int) big ;

    Code compiled with this new compiler will suffer a fatal run time error
    when this code is run.  Note that 600000 will not fit into an int on
    this machine, but will fit into a long.  I thought that my explicit cast
    would tell the compiler to do whatever was needed to stuff the long into
    the int [2].  Does the ANSI standard allow the run time lib to overflow 
    here?  If the run time library is correct in generating an error then all 
    (portable) casts from long to int must be done like this:

    small = (int) (big&UINT_MAX) ;  /*I'm assuming that UINT_MAX is all ones*/

In which (if any) of these three cases is the compiler broken?

[1] This is my interpretation of page 55 of the Rationale, dated Jan. 11, 1988:
"An implementation may thus assume that all other [non prototyped] functions 
are called with a fixed  argument list"

[2] K&R says (on page 42): "Longer int's are converted to shorter ones or to 
char's by dropping the excess high-order bits." Did ANSI drop this requirement?

Josh

Name:         Joshua Levy  (415) 424-0500x509
Disclaimer:   Teknowledge can plausibly deny everything.
Pithy Quote:  "Keep your lawyers off my computer!"  -- GNU (?)
jlevy at teknowledge-vaxc.arpa or 
{uunet|sun|ucbvax|decwrl}!jlevy%teknowledge-vaxc.arpa



More information about the Comp.lang.c mailing list