X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f From: "Bob W" Newsgroups: comp.os.msdos.djgpp Subject: Sequence points, any? Date: 5 Apr 2006 05:00:53 -0700 Organization: http://groups.google.com Lines: 109 Message-ID: <1144238453.674596.302360@z34g2000cwc.googlegroups.com> NNTP-Posting-Host: 84.102.38.22 Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" X-Trace: posting.google.com 1144238460 4629 127.0.0.1 (5 Apr 2006 12:01:00 GMT) X-Complaints-To: groups-abuse AT google DOT com NNTP-Posting-Date: Wed, 5 Apr 2006 12:01:00 +0000 (UTC) User-Agent: G2/0.2 X-HTTP-UserAgent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727),gzip(gfe),gzip(gfe) Complaints-To: groups-abuse AT google DOT com Injection-Info: z34g2000cwc.googlegroups.com; posting-host=84.102.38.22; posting-account=CXf2IQ0AAADhHwR4LIBYSPHMQKV3cPd3 To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com Before reporting a gcc bug I would like to consult the experienced public in this newsgroup for their opinions: As mentioned already in a previous post, gcc 4.10 tends to optimize code in a way so that it gets out of sequence. This happens already in a simple program which is meant to do the following: - call clock() to start timing - call a recursive function 'Ack(..)' - call clock() again to get the time elapsed - display timing After compilation the code is rearranged by gcc the following way: - Ack(..) gets modified by gcc - gcc calls clock() to start timing - Ack() is called the 1st time - gcc calls clock() again to end the timing - now Ack() is called again and this obsoletes timing - just timing of the 1st Ack() call gets displayed I have not made up my mind whether I'd consider this a genuine bug or not. Theoretically the compiler needs the results of Ack() only when the printf() statement is being executed. So gcc seemingly does not care whether the Ack() result is finally available before clock() is called the second time. Unfortunately this does not match the programmer's expectations and after trying several methods of getting gcc to compile in sequence with Ack() and clock() calls I have found the following solutions: - assign the return value of Ack() to a static or global variable instead of using a local var - 'hide' the second clock() call after the first printf() statement The following methods did not work in finding a way to prevent gcc rearranging code sequence: - declaring variables for clock() timing values as global, static or extern - calling clock() a third time in order to get gcc to interleave its second call to Ack() between the 2nd and 3rd call to clock() as it is obviously done if a printf() statement is used instead of clock() - using a do {..} while loop to call Ack() e.g.: do { ackret=Ack(..); } while(0); One further observation: If gcc's out-of-sequence optimisation is prevented by using one of the methods mentioned previously, the program actually executes a touch faster. So from the programmer's point of view gcc's behaviour of breaking the sequence cannot be considered beneficial. Finaly, here is a sample program which will demonstrate the 'maybe-bug' - unless the /* static */ is uncommented (use parameters of 11 or 12 if you actually want to try it out): ------------------------------- #include #include #include extern clock_t t0,t1,t2; extern int n; int Ack(int m, int n) { return(m ? (Ack(m-1,n ? Ack(m,(n-1)) : 1)) : n+1); } int main(int ac, char **av) { /* static */ int ackret; n = (ac == 2) ? atoi(av[1]) : 1; t0=clock(); do { ackret=Ack(3, n); } while(0); t1=clock(); printf("Ack(3,%d): %d\n", n, ackret); t2=clock(); printf("Time1: %g secs\n", 1.0*(t1-t0)/CLOCKS_PER_SEC); printf("Time2: %g secs\n", 1.0*(t2-t0)/CLOCKS_PER_SEC); printf("t2:%d, t1:%d, t0:%d, cps:%d\n",t2,t1,t0,CLOCKS_PER_SEC); return 0; }