[comp.lang.c] Nude Vicar in Sex Romp!

yuleat@prlhp1.prl.philips.co.uk (yuleat) (08/15/89)

Now that I've got your attention, why not consider the following
piece of code (which has nothing to do with nude vicars!) :

#include <stdio.h>

main()
 {
    float x= 0.1234;

    fn1(x);
 }

fn1(x)
float x;
 {
    float y= x;

    fn2(&x, &y);
 }

fn2(x, y)
float *x, *y;
 {
    printf("In fn2 values are x= %f & y= %f\n", *x, *y);
 }


The interesting thing is that on both the compilers (HP & Apollo)
I've tried this on, the values printed out by the printf() are
different. Specifically, x is gibberish, whilst y is correct
(0.1234).  I believe that the reason for this is that x in main()
is converted to a double as it is passed to fn1(), thus the pointer
that is passed to fn2() is really a pointer to a double and hence
when it is de-refernced as a pointer to a float, it gets the "wrong"
answer.

What I would like to know is whether this is what the compiler
should do (I've looked in K&R and I couldn't find anything
that addressed this problem specifically).

----------------------------------------------------------------------
Andy Yule                                       Philips Research Labs,
(yuleat@prl.philips.co.uk)                           Redhill, England.
======================================================================

dan@oresoft.uu.net (Daniel Elbaum) (08/18/89)

The pANS requires that floats be promoted to double for
function calls unless the function is prototyped as
taking float arguments.  Classic C doesn't constrain
compilers to promote.
-- 
Spa link snot the temper tent, a few cannery doubt lowed.

({uunet,tektronix,reed,sun!nosun,osu-cis,psu-cs}!oresoft!(dan)@oresoft.uu.net)

walter@hpclwjm.HP.COM (Walter Murray) (08/18/89)

Andy Yule writes:

> #include <stdio.h>
> main()
>  {
>     float x= 0.1234;
>     fn1(x);
>  }
> fn1(x)
> float x;
>  {
>     float y= x;
>     fn2(&x, &y);
>  }
> fn2(x, y)
> float *x, *y;
>  {
>     printf("In fn2 values are x= %f & y= %f\n", *x, *y);
>  }

> [Conjecture as to why the first value printed is gibberish]

> What I would like to know is whether this is what the compiler
> should do (I've looked in K&R and I couldn't find anything
> that addressed this problem specifically).

A number of C implementations do this.  In fn1(), the compiler is
rewriting the type of x to double, knowing that that's how it is
going to be passed.  All behavior will be exactly as though you
had written 'double x' rather than 'float x'.  Try printing
sizeof(x) and you will see that it is equal to sizeof(double),
not sizeof(float).

Your understanding of what is happening is correct.  Some compilers
do this type rewriting for integral parameter types as well as for
floating types, although HP only does it for floating types.

You will be glad to know that the dpANS outlaws this behavior.
Run your program on an ANSI-conforming compiler and it will
print 0.123400 for both *x and *y.  If you have a copy of the
dpANS, see section 3.7.1 of the Rationale.

Walter Murray
----------

ccdn@levels.sait.edu.au (DAVID NEWALL) (08/18/89)

In article <960@prlhp1.prl.philips.co.uk>, yuleat@prlhp1.prl.philips.co.uk (yuleat) writes:
> Now that I've got your attention, why not consider the following
> piece of code (which has nothing to do with nude vicars!) :
>
> [ code deleted ]
>
> The interesting thing is that on both the compilers (HP & Apollo)
> I've tried this on, the values printed out by the printf() are
> different. Specifically, x is gibberish, whilst y is correct
> (0.1234).  I believe that the reason for this is that x in main()
> is converted to a double as it is passed to fn1(), thus the pointer
> that is passed to fn2() is really a pointer to a double and hence
> when it is de-refernced as a pointer to a float, it gets the "wrong"
> answer.

Page 41, K&R:
        "Notice that all float's in an expression are converted to double;
    all floating point arithmetic in C is done in double precision."

Page 42, K&R:
        "Since a function argument is an expression, type conversions also
    take place when arguments are passed to functions: in partuclar, ...
    float becomes double.  This is why we have declared function arguments
    to be ... double even when the funciton is called with ... float."

The question is not why x in main() is passed as a double, but rather, why
the compiler doesn't warn you when you declare x in fn1() as a float.

For the record, I get the same result on an NCR Tower 32/400 (Tower OS 2.01)
and a Sun 3/60 (SunOS 4.0.3)


David Newall                     Phone:  +61 8 343 3160
Unix Systems Programmer          Fax:    +61 8 349 6939
Academic Computing Service       E-mail: ccdn@levels.sait.oz.au
SA Institute of Technology       Post:   The Levels, South Australia, 5095

devine@shodha.dec.com (Bob Devine) (08/22/89)

In article <960@prlhp1.prl.philips.co.uk>, yuleat@prlhp1.prl.philips.co.uk (yuleat) writes:
> fn2(x, y)
> float *x, *y;
>  {
>     printf("In fn2 values are x= %f & y= %f\n", *x, *y);
>  }
> 
> What I would like to know is whether this is what the compiler
> should do (I've looked in K&R and I couldn't find anything
> that addressed this problem specifically).

  Check out the sections on parameter widening.  The floats (likely
these are 4 bytes) are being widened to doubles (8 bytes) so when
you use a `float *' you are only getting 1/2 the number.  On some
machines a hardware check for a valid floating point number is made
so if you had bad luck to select the wrong bit pattern the program
would have dumped with a very misleading error!

Bob Devine

lmb@ibmpa.UUCP (Larry Breed) (08/24/89)

In article <1989Aug17.191545.13040@oresoft.uu.net> dan@oresoft.uu.net (Daniel Elbaum) writes:
>
>The pANS requires that floats be promoted to double for
>function calls unless the function is prototyped as
>taking float arguments.  Classic C doesn't constrain
>compilers to promote.

K&R does indeed require compilers to promote floating args to double.
This matches the pANS when there's no prototype visible.


-- 
Larry Breed
inet: lmb%ibmsupt@uunet.uu.net
uucp: uunet!ibmsupt!lmb		(415) 855-4460

dan@oresoft.uu.net (Daniel Elbaum) (08/25/89)

In article <1827@ibmpa.UUCP> lmb@ibmpa.UUCP (Larry Breed) writes:
:In article <1989Aug17.191545.13040@oresoft.uu.net> dan@oresoft.uu.net (Daniel Elbaum) writes:
:>... Classic C doesn't constrain :>compilers to promote.
:
:K&R does indeed require compilers to promote floating args to double.
:This matches the pANS when there's no prototype visible.

True enough, though not all compilers obeyed the constraint.

My dog peed on that page of K&R.
-- 
Spa link snot the temper tent, a few cannery doubt lowed.

({uunet,tektronix,reed,sun!nosun,osu-cis,psu-cs}!oresoft!(dan)@oresoft.uu.net)