Path: utzoo!mnetor!uunet!lll-winken!lll-lcc!lll-tis!ames!amdcad!cae780!leadsv!laic!darin From: darin@laic.UUCP (Darin Johnson) Newsgroups: comp.os.vms Subject: Re: C puzzle Message-ID: <164@laic.UUCP> Date: 23 Feb 88 19:54:56 GMT References: <8802221044.AA21745@ucbvax.Berkeley.EDU> Organization: Lockheed AI Center, Menlo Park Lines: 54 Summary: Not just a VMS problem In article <8802221044.AA21745@ucbvax.Berkeley.EDU>, hamm@BIOVAX.RUTGERS.EDU writes: > We recently had to port a C program from Unix to VMS, and one of the many > things which exploded was a line looking like this: > > for (i=0;i > From the context, I assumed that what was intended was: > > for (i=0;i > whereas what I thought would happen based on my limited knowledge of C was: > > for (i=0;i > which would certainly explain the resulting walk in address space when the > three arrays are of size [LIMIT]. > > A test program shows that /*3*/ is indeed what happens under VMS, but that > /*2*/ is what happens under (Sun) Unix. > > I've looked in vain (though perhaps not thoroughly enough) in K&R for a > precise definition of when increments such as i++ or ++i should be done; This is a very common portability problem. The problem is not with the compilers, but the fact that the original code made assumptions about the compiler. The time at which "i++" is evaluated can not be determined (this may not be emphasized enough in K&R)!! Different compilers will do this at different times. Some people may assume that "i++" means i gets incremented after the expression is finished, but this is false for a lot of compilers. Since VAX C optimizes code much better than Sun it re-ordered the code so that the increment was done before looking at c2 or c3. Note that this problem is NOT unique to VMS. Similar (but different) problems will also be found between the Suns compiler and a VAX BSD compiler. Probably, the main reason code like this abounds, is that a lot of UNIX compilers don't optimize well, and the programmers tend to optimize the code themselves (even worse is the problem of UNIX implementor's who know about the compiler's internals and program accordingly). Perhaps if people porting UNIX were more concerned with good compilers than with getting UNIX running ASAP.... Anyway, back to the problem. The only way you can know what the code intended is to examine the results of the same program compiled on the original machine it was written on (assuming it ever worked 'correctly'). If this is a pain, then look at the context and comments (What? No comments!? :-) PS: I tried this out on a Sun with "lint" and I indeed get the message - test.c(14): warning: i evaluation order undefined -- Darin Johnson (...ucbvax!sun!sunncal!leadsv!laic!darin) (...lll-lcc.arpa!leadsv!laic!darin) All aboard the DOOMED express!