[comp.lang.c] A define problem

siva@bally.Bally.COM (Siva Chelliah) (01/08/91)

#define half(x) (x)/2
main ()
{
  int i=5;
  printf( "i/2 = %d\n",half(i-5));
}

This program prints 3 instead of 0 !  How can I make it print 0 ?

Thanks 

Siva

hunter@Oswego.EDU (Eric Hunter) (01/08/91)

In article <440@bally.Bally.COM> siva@bally.Bally.COM (Siva Chelliah) writes:

>#define half(x) (x)/2
>main ()
>{
>  int i=5;
>  printf( "i/2 = %d\n",half(i-5));
>}
>This program prints 3 instead of 0 !  How can I make it print 0 ?

You could get a new compiler. ;^}

Eric.
-------------------------------------------------------------------------
 The difference between emacs, and vi, |  hunter@oswego.oswego.edu
 is like the difference between        |  {rutgers}!sunybcs!oswego!hunter
 making love, and masturbation.        |  hunter@snyoswva.bitnet 

md@sco.COM (Michael Davidson) (01/09/91)

In article <440@bally.Bally.COM> siva@bally.Bally.COM (Siva Chelliah) writes:
>#define half(x) (x)/2
>main ()
>{
>  int i=5;
>  printf( "i/2 = %d\n",half(i-5));
>}
>This program prints 3 instead of 0 !  How can I make it print 0 ?

Compile it with a C compiler perhaps??
If you compiled precisely this sample code and got 3 written to
standard output instead of 0 then you have, at best, a broken C compiler.

mcdaniel@adi.com (Tim McDaniel) (01/09/91)

I suspect that the program Siva Chelliah actually compiled had
   #define half(x)  x /2
without the paren- ^ ^ theses.  In that case, half(i-5) is 3 when i==5.

Rule of thumb: PARENTHESIZE THE RESULT OF A MACRO, AND PARENTHESIZE
THE USE OF EACH ARGUMENT.

Even
   #define half(x) (x)/2
fails, if someone uses it in an expression with an operator with
higher precedence than /, as in
   ~half(i)
This Silly Little Macro should be written as
   #define half(x) ((x)/2)

--
Tim McDaniel                 Applied Dynamics Int'l.; Ann Arbor, Michigan, USA
Work phone: +1 313 973 1300                        Home phone: +1 313 677 4386
Internet: mcdaniel@adi.com                UUCP: {uunet,sharkey}!amara!mcdaniel

stanley@phoenix.com (John Stanley) (01/10/91)

jak@sactoh0.SAC.CA.US (Jay A. Konigsberg) writes:

> In article <1991Jan8.012923.3390@oswego.Oswego.EDU> hunter@oswego.Oswego.EDU 
> >In article <440@bally.Bally.COM> siva@bally.Bally.COM (Siva Chelliah) writes
> >
> >>#define half(x) (x)/2
> >>main ()
> >>{
> >>  int i=5;
> >>  printf( "i/2 = %d\n",half(i-5));
> >>}
> >>This program prints 3 instead of 0 !  How can I make it print 0 ?
> >
> >You could get a new compiler. ;^}
> >
> 
> Bzzzt. Wrong, but thank you for playing :-)
> 
> Look at what is being passed to "half()".

    Bzzzzt. Wrong, but thank YOU for playing. There is nothing "passed"
to half(). Half is a preprocessor macro that is expanded by the
preprocessor, and not a function to which things are passed. 

> i=5
> half(i-5) or half(5-5) or half(0)

   Do you REALLY think the preprocessor is smart enough to perform the 
subtraction and expand the macro "half" with a parameter of 0? To the
preprocessor, (i-5) is not the same as (5-5) is not the same as (0).

> which becomes: (0)/2 - which is 0.

   Try "i-5/2".

   It looks like the preprocessor is discarding the () around the x in
the macro expansion. Instead of generating the expression "(i-5)/2" it
is generating "i-5/2". "5/2" is 2 (integer arithmetic), and 5-2 is 3. One
would think the preprocessor should honor the existing (), but it must 
not be doing it. Try running just the preprocessor and looking at the
generated code. You might not need a whole new compiler, just the
preprocessor.

   As was previously suggested, try defining half(x) as ((x))/2. Or, if
all you want is a way to print 0 (which is all you said you wanted -- "How
do I make it print 0?") then replace the expression "half(i-5)" in the
printf with "0". :-)


   Since one reason to use #defines is to shorten the amount of typing,
why not just do the division yourself? You save two characters in each
use.

kdq@demott.com (Kevin D. Quitt) (01/10/91)

In article <4613@sactoh0.SAC.CA.US> jak@sactoh0.SAC.CA.US (Jay A. Konigsberg) writes:
>
>Look at what is being passed to "half()".
>
>i=5
>half(i-5) or half(5-5) or half(0)
>
>which becomes: (0)/2 - which is 0.
>
>It looks like it should be:
>
>printf( "i/2 = %d\n",half(i));
>
>which produces 2, not 3 anyway. If you want to round up, you should
>define the variables as a float, add .5 and cast to (int).


    or half(i+1)


-- 
 _
Kevin D. Quitt         demott!kdq   kdq@demott.com
DeMott Electronics Co. 14707 Keswick St.   Van Nuys, CA 91405-1266
VOICE (818) 988-4975   FAX (818) 997-1190  MODEM (818) 997-4496 PEP last

greywolf@unisoft.UUCP (The Grey Wolf) (01/17/91)

In article <4613@sactoh0.SAC.CA.US> jak@sactoh0.SAC.CA.US (Jay A. Konigsberg) writes:
>In article <1991Jan8.012923.3390@oswego.Oswego.EDU> hunter@oswego.Oswego.EDU (Eric Hunter) writes:
>>In article <440@bally.Bally.COM> siva@bally.Bally.COM (Siva Chelliah) writes:
>>
>>>#define half(x) (x)/2
>>>main ()
>>>{
>>>  int i=5;
>>>  printf( "i/2 = %d\n",half(i-5));
>>>}
>>>This program prints 3 instead of 0 !  How can I make it print 0 ?
>>
>>You could get a new compiler. ;^}
>>
>
>Bzzzt. Wrong, but thank you for playing :-)

Bzzzzt.  Wrong, but thank you for replying :-)

>
>Look at what is being passed to "half()".

Nothing's wrong with it...

>
>i=5
>half(i-5) or half(5-5) or half(0)
>
>which becomes: (0)/2 - which is 0.

Exactly the problem.  Siva WANTS that to happen, but is getting 3 instead!

>
>It looks like it should be:
>
>printf( "i/2 = %d\n",half(i));
>
>which produces 2, not 3 anyway. If you want to round up, you should
>define the variables as a float, add .5 and cast to (int).

You are attempting to rewrite someone else's logic after they explicitly
state what they want.

It seems to be general consensus that Siva's C compiler is broken.
-- 
On the 'Net:  Why are more and more fourth-level wizard(-wannabe)s trying to
invoke ninth-level magic, instead of taking the time to climb the other
(quite essential) thirteen levels so they can do this properly?
...!{ucbvax,acad,uunet,amdahl,pyramid}!unisoft!greywolf