[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference turris::decc

Title:DECC
Notice:General DEC C discussions
Moderator:TLE::D_SMITHNTE
Created:Fri Nov 13 1992
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:2212
Total number of notes:11045

2209.0. "-oldc -migrate different results" by NNTPD::"[email protected]" (clemens esser) Tue Jun 03 1997 09:56

Hi,

I have got some code from a customer that provides different
results when he uses different compiler versions.

Digital UNIX V4.0B is the operating system.

cflags -migrate runs the program but wrong results
cflags -oldc    produces correct results
cflags -newc    produces a segmentation violation.

We where able to narrow it down to 1 subroutine that is below.
We need a whole environment to run the program but I can make
it available if required.

Now I can compile everything with -migrate and only this
subroutine with -oldc and then link everything together.

Any hint on errors in the code or whatever you might guess.
 
The code runs on Ultrix, SGI, SUN , HP and Digital UNIX v3.2x.

Clemens Esser

===============================================================
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "constants.h"
#include "variables.h"
#include "functions.h"
/*
NR=15; NZ=25;
vardefs.h:int    fl[NR+2][NZ+2];
vardefs.h:double pres[NR+2][NZ+2];            /* Pressure field [Pa]          
/
vardefs.h:double dP_dr[NR+2][NZ+2];           /* pressure gradient r-direction
/
vardefs.h:double dP_dz[NR+2][NZ+2];           /* pressure gradient z-direction
/
i runs from 1-15 and j from 1-25

The dP_dr and dP_dz arrays will end up with wrong results
*/


void GRADIENTS(int i, int j)
{

double P_top, P_bot, P_left, P_right;

  if (fl[i][j]==1)
    {


      if((fl[i-1][j] == 2) || (fl[i-1][j] == 3))
        {
          P_right = pres[i+1][j];
          P_left = pres[i][j];
        }

      if((fl[i+1][j] == 2) || (fl[i+1][j] == 3))
        {
          P_right = pres[i][j];
          P_left = pres[i-1][j];
        }

      if(fl[i][j-1] == 4)
        {
          P_top = pres[i][j+1];
          P_bot = pres[i][j  ];
        }

      else {
        P_top = 0.5 * (pres[i  ][j+1] + pres[i  ][j  ]);
        P_bot = 0.5 * (pres[i  ][j-1] + pres[i  ][j  ]);
        P_right = 0.5 * (pres[i+1][j  ] + pres[i  ][j  ]);
        P_left = 0.5 * (pres[i-1][j  ] + pres[i  ][j  ]);
      }

      dP_dz[i][j] = (P_top - P_bot) / DZ;
      dP_dr[i][j] = (P_right - P_left) / DR;

    } /* if fl[i][j] == 1 */

} /* GRADIENTS */




[Posted by WWW Notes gateway]
T.RTitleUserPersonal
Name
DateLines
2209.1Nothing obvious except...WIBBIN::NOYCEPulling weeds, pickin&#039; stonesTue Jun 03 1997 11:296
What should P_right and P_left be set to if
	(fl[i][j-1] == 4) is true and
((fl[i-1][j] == 2) || (fl[i-1][j] == 3)) is false and
((fl[i+1][j] == 2) || (fl[i+1][j] == 3)) is false?

Or can you be sure this never happens?
2209.2Sounds familiar...DECC::SULLIVANJeff SullivanTue Jun 03 1997 11:3940
We sometimes hear reports of this type of runtime differences due to the use of
a different compiler or different compiler options. Although we have seen some
optimization bugs in the compiler, many of the runtime errors have been due to
latent bugs in the source code. We are very interested in helping find out if
this is a compiler or a source code problem. Helping with migration problems
from other UNIXes or prior versions of Digital UNIX is a high priority for us.

There are a few notes in here that describe why non-conforming C prgrams that
used to "work" on other UNIXes now will fail using DEC C on Digital UNIX. I'll
see if I can dig up a pointer to one or two... 

Having said that, here are a couple of things that you might try. We would do
this on our side, but we would probably need the standalone program and the
expected results.

1) Try -noansi_alias if you are compiling -std/-std1 to see if the problem "goes
away". This is not applicable if compiling in -std0 (K&R mode), which is the
default for the V4.0B compiler.

2) Check the cc man page. This describes the differences in optimization levels
for both 'cc -migrate' and 'cc -new' (both are DEC C, but the optimization and
tuning differs). Try running the same test at lower optimizations to see if the
problem "goes away".

3) Try instrumenting the program with atom third degree. See man atom, man
third. This is a "Purify" like  memory verifier that will check for overwrites
or uninitialized data at runtime. This is usually the most useful tool in
finding latent bugs that happen to surface on Digital UNIX (but were hidden on
other O/Ses).

See also
   http://www.zk3.dec.com/dude/program_analysis/

and section 7 of the Programmer's Guide 
   http://www.zk3.dec.com/~binder/platinum/AA-PS30D-TET1_html/peg8.html


Let us know what you find out after trying the above.

-Jeff
2209.3DECCXL::MARIOTue Jun 03 1997 17:462
Can you supply the full cc command line you are using?

2209.4source code errorNNTPD::&quot;[email protected]&quot;Clemens EsserWed Jun 04 1997 04:5132
Hi,

I tried several things. 

The compiler options where very simple
cc -<compiler> -c source1.c
cc -<compiler> -c source2.c
cc -o object source1.o source2.o

And <compiler> was -oldc or -newc or -migrate
-oldc gave correct results (aka same results as other compilers)
-migrate gave wrong results
-newc produces segmentation violation

Using lower optimization levels did not result in different answers.

As said in .1 P-left and P-right where uninitialised.

Making them "static" made the -migrate produce the "correct" results.
This solved the customers problem. Now he is testing in the real program. 
The test case also introduces the crash with newc but in the original code 
it does not crash.

He aggreed it was an C source code error and he was glad our compiler found
it.
He could not tell me for sure the other compilersproduced real good results.

Now he will use Third to search for other problems. And I am pretty sure
we will sell at least 2 new workstations in this new account. 

Thanks.  
[Posted by WWW Notes gateway]
2209.5Making it static is no solutionWIBBIN::NOYCEPulling weeds, pickin&#039; stonesWed Jun 04 1997 09:3639
> Making them "static" made the -migrate produce the "correct" results.
> This solved the customers problem. 

I hope he doesn't think this is the proper solution!  That just means
that when the routine neglects to set P_left and P_right it will use
some leftover value from the previous call.  While that should get the
same value with every compiler (except for the very first call), there's
nothing in the physics to justify that choice -- especially if the
previous call differed in both i and j!

More likely, he wants to structure it something like this, to be sure
that each variable gets an appropriate value:


      if((fl[i-1][j] == 2) || (fl[i-1][j] == 3)) {
          P_right = pres[i+1][j];
          P_left = pres[i][j];
      }
      else if((fl[i+1][j] == 2) || (fl[i+1][j] == 3)) {
          P_right = pres[i][j];
          P_left = pres[i-1][j];
      }
      else {
          P_right = 0.5 * (pres[i+1][j  ] + pres[i  ][j  ]);
          P_left = 0.5 * (pres[i-1][j  ] + pres[i  ][j  ]);
      }

      if(fl[i][j-1] == 4) {
          P_top = pres[i][j+1];
          P_bot = pres[i][j  ];
      }
      else {
          P_top = 0.5 * (pres[i  ][j+1] + pres[i  ][j  ]);
          P_bot = 0.5 * (pres[i  ][j-1] + pres[i  ][j  ]);
      }

      dP_dz[i][j] = (P_top - P_bot) / DZ;
      dP_dr[i][j] = (P_right - P_left) / DR;

2209.6static storage must be initialized to zero if not explicitly initializedVESPER::VESPEROpenGL Alpha GeekWed Jun 04 1997 10:1319
Just a very minor point.

>I hope he doesn't think this is the proper solution!  That just means
>that when the routine neglects to set P_left and P_right it will use
>some leftover value from the previous call.  While that should get the
>same value with every compiler (except for the very first call), there's
                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>nothing in the physics to justify that choice -- especially if the
>previous call differed in both i and j!

For the very first call, wouldn't they contain zeros for all compilers?
In other words, aren't the two declarations below equivalent:

static int	j;
static int	j = 0;

Section 3.5.7 (ANSI version) Initialization requires this.

Andy V
2209.7DECC::OUELLETTEblackflies upgraded to mosquitosWed Jun 04 1997 18:091
Yes, all static variables (local or file scope) are implicitly zero initialized.