[comp.lang.c] interesting program

jeffl@berick.UUCP (Jeff Lawhorn) (01/30/88)

After watching all the flame wars here I decided that it was time to
start one of my own  ;)

What does the following program print?  (I know of at least one
program that prints the wrong answer).

main()
{
	int k = 4;
	k = k++;
	printf("and the answer is %d\n", k);
	exit(0);
}
-- 

Everything should be made as simple      Jeff Lawhorn
  as possible, but no simpler.           jeffl@berick.uucp
                                         ...!sdcsvax!sdsu!berick!jeffl

crowl@cs.rochester.edu (Lawrence Crowl) (01/30/88)

In article <19@berick.UUCP> jeffl@berick.UUCP (Jeff Lawhorn) writes:
]What does the following program print?  (I know of at least one
]program that prints the wrong answer).
]
]main() {
]	int k = 4;
]	k = k++;
]	printf("and the answer is %d\n", k);
]	exit(0);
]}

This program is ambiguous.  The statement "k = k++;" depends on the order
of evaluation, which is undefined.  Valid C implementation may print
either 4 or 5.  So, unless the C compiler in question is really bad, it
does not provide a "wrong" answer.  Consider the following legal executions
for the statement in question:

    r := k ;                      r := k ;
    k := k + 1 ;                  k := r ;
    k := r ;                      k := k + 1 ;

Both meet the standard, but yield different results.
-- 
  Lawrence Crowl		716-275-9499	University of Rochester
		      crowl@cs.rochester.edu	Computer Science Department
...!{allegra,decvax,rutgers}!rochester!crowl	Rochester, New York,  14627

chris@mimsy.UUCP (Chris Torek) (01/30/88)

In article <19@berick.UUCP> jeffl@berick.UUCP (Jeff Lawhorn) writes:
>After watching all the flame wars here I decided that it was time to
>start one of my own  ;)   What does the following program print?

and the program contains the line

>	k = k++;

The only flame this deserves is `RTFM'.  Or in this case, as someone
put it, RTFK&R.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

ark@alice.UUCP (01/30/88)

In article <19@berick.UUCP>, jeffl@berick.UUCP writes:
> What does the following program print?  (I know of at least one
> program that prints the wrong answer).

> {
> 	int k = 4;
> 	k = k++;
> 	printf("and the answer is %d\n", k);
> 	exit(0);
> }

Saying "the wrong answer" implies that there is a right answer.
In fact, the result of this program is undefined, because the
implementation is permitted to

	fetch k
	increment k
	store old value of k in k

(in which case the result is 4), or

	fetch k
	store old value of k in k
	increment k

(in which case the result is 5).

daveb@laidbak.UUCP (Dave Burton) (01/31/88)

In article <19@berick.UUCP> jeffl@berick.UUCP (Jeff Lawhorn) writes:
>What does the following program print?  (I know of at least one
>program that prints the wrong answer).
>
>main()
>{
>	int k = 4;
>	k = k++;
>	printf("and the answer is %d\n", k);
>	exit(0);
>}

Ambiguity warning:
According to K&R, App A, page 187:
"When the postfix ++ is applied to an lvalue the result is the value of the
 object referred to by the lvalue. After the result is noted, the object is
 incremented in the same manner as for the prefix ++ operator."

 The ambiguous word here is "noted".
 This text does not state when assignment is performed.
 "Normal":

 movl	#4,-4(a6)	| k = 4
 addql	#1,-4(a6)	| k = k++

 However, the compiler could note the result, then produce code accordingly:

 movl	#4,-4(a6)	| k = 4
 movl	-8(a6),-4(a6)	| [tmp = k]	noted
 addql	#1,-4(a6)	| k++		incremented
 movl	-4(a6),-8(a6)	| k = tmp	assignment

I think the result is arguably 5, but acknowledge
a result of 4 *could* be considered correct.

Flames to /dev/null, corrections to /dev/lp.
-- 
--------------------"Well, it looked good when I wrote it"---------------------
 Verbal: Dave Burton                        Net: ...!ihnp4!laidbak!daveb
 V-MAIL: (312) 505-9100 x325            USSnail: 1901 N. Naper Blvd.
#include <disclaimer.h>                          Naperville, IL  60540

mrd@sun.soe.clarkson.edu (Mike DeCorte) (02/01/88)

Posting-Front-End: GNU Emacs 18.47.5 of Mon Jan 25 1988 on sun.soe.clarkson.edu (berkeley-unix)


In article <19@berick.UUCP> jeffl@berick.UUCP (Jeff Lawhorn) writes:

   After watching all the flame wars here I decided that it was time to
   start one of my own  ;)

   What does the following program print?  (I know of at least one
   program that prints the wrong answer).

   main()
   {
	   int k = 4;
	   k = k++;
	   printf("and the answer is %d\n", k);
	   exit(0);
   }

There is no wrong answer to this! (assuming you answer either 4 or 5)
They are both right!

Reread page 50 of K&R.  If you have not read K&R DON'T tell people
what is and is not correct.

Here are the two possible interpetations.

1)
rk = 4  	(rk for rvlaue)
put rk into lk  (lk for lvalue)
increment lk    (value of lk = 5 now)

final answer = 5

2)
rk = 4  	(rk for rvlaue)
increment lk    (value of lk = 5 now)
put rk(4) into lk  (lk for lvalue)

final answer = 4

-- 
Michael DeCorte
mrd@clutx.clarkson.edu
mrd@clutx.bitnet

trt@rti.UUCP (Thomas Truscott) (02/01/88)

> ... What does the following program print?
> ...
>	k = k++;

Gems like this are posted to Usenet every month or so (it seems),
to which a typical response might be:

> The only flame this deserves is `RTFM'.
[note: page 50 of the K+R C book.]

I wish the responses would instead be something like
"It is a crime that your compiler misses blatant errors such as that."
If we all said bad things about compilers that passed such code
I bet the vendors would fix them!  Maybe even AT&T.

To those who feel that such checking belongs in lint and not in cc, I ask:
Don't current C compilers already have dozens of different warning
messages, such as "unsigned >= always true"?
Is it wrong to add another which will save man-years of debugging
(not to mention man-years of time spent reading comp.unix.c)?
	Tom Truscott

jesse@rlgvax.UUCP (Jesse Barber) (02/04/88)

In article <19@berick.UUCP>, jeffl@berick.UUCP (Jeff Lawhorn) writes:
> What does the following program print?  (I know of at least one
> program that prints the wrong answer).
> 
> main()
> {
> 	int k = 4;
> 	k = k++;
> 	printf("and the answer is %d\n", k);
> 	exit(0);
> }

What the program prints depends on the compiler used. I used two compilers
msc 4.0 and CCI's 6/32 compiler.
msc printed 4
cci printed 5

However, neither of these compilers is wrong. Remember the old adage
      " It's a poor workman that blames his tools"
On page 49 of K&R copyright 1978 it states
"C, like most languages, does not specify in what order the operands of
an operator are evaluted"

The two results I got are because the two compilers evaluated the operands
of the "=" in a different order.

msc:
       tmp = k;        /* evaulate k */
       k = k + 1;            /* evaluate k++ */
       k = tmp;        /* evaluate = */

cci:
       k = k;          /* evaluate = */
       k = k + 1;      /* evaluat k++ */

As a matter of fact, K&R use the increment operator to demonstrate this
kind of problem.

Notice that in code which does not depend on the order of evaluation
both compilers produce "correct" responses.
-- 
..!seismo!rlgvax!jesse ( Jesse @ C.C.I. Reston, Va.)

Have brain, will travel