www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - compiled program error

reply "John Nixon" <jhn nixon.com> writes:
While developing with D (DMD64 D Compiler v2.067.0 on MacOS 
10.10.3) I had a program with an unexpected behaviour
and I reduced it to the minimal form below. The error as 
indicated in the comment is that the function call pvi_calc 
changes int_1 when I think it should not. The result copied below.

I hope this helps. Kind regards
John Nixon


import std.stdio;
int n,cp;
double[] pvi,int_1,int_2;

void pvi_centre(const int centre){
   int_1=pvi_calc(centre);
   writeln("int_1 = ",int_1);
   int_2=pvi_calc(n-1-centre);//pvi_calc is changing int_1!
   writeln("int_1 = ",int_1);
   return;}

double[] pvi_calc(const int n1){
   for(int i=0;i<=n1;++i)pvi[i]= 1;
   return pvi;}

int main(){
   n=10;
   pvi.length=n;
   int_1.length=int_2.length=n;
   pvi_centre(cp);
   return 0;}
~

int_1 = [1, nan, nan, nan, nan, nan, nan, nan, nan, nan]
int_1 = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
Jun 07 2015
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Sunday, 7 June 2015 at 18:59:00 UTC, John Nixon wrote:
 double[] pvi,int_1,int_2;

   int_1=pvi_calc(centre);
   int_2=pvi_calc(n-1-centre);//pvi_calc is changing int_1!
 double[] pvi_calc(const int n1){
   return pvi;}
These are the relevant lines: pvi_calc writes to a global array (pvi) then returns it. So the first two lines are just setting int_1 and int_2 both to pvi, the same thing. So since they all reference the same array, writing to any of them changes all of them. You'll probably want to move double[] pvi to inside pvi_calc so it becomes a new copy, or at least `return pvi.dup;` instead of just `return pvi;`
Jun 07 2015
parent "John Nixon" <jhn nixon.com> writes:
On Sunday, 7 June 2015 at 19:05:16 UTC, Adam D. Ruppe wrote:
 On Sunday, 7 June 2015 at 18:59:00 UTC, John Nixon wrote:
 double[] pvi,int_1,int_2;

  int_1=pvi_calc(centre);
  int_2=pvi_calc(n-1-centre);//pvi_calc is changing int_1!
 double[] pvi_calc(const int n1){
  return pvi;}
These are the relevant lines: pvi_calc writes to a global array (pvi) then returns it. So the first two lines are just setting int_1 and int_2 both to pvi, the same thing. So since they all reference the same array, writing to any of them changes all of them. You'll probably want to move double[] pvi to inside pvi_calc so it becomes a new copy, or at least `return pvi.dup;` instead of just `return pvi;`
Thank you for your concise reply. I had forgotten the distinction between arrays and slices that is described in Ali Chehreli's book Programming in D. John Nixon
Jun 07 2015
prev sibling parent "tcak" <tcak gmail.com> writes:
On Sunday, 7 June 2015 at 18:59:00 UTC, John Nixon wrote:
 While developing with D (DMD64 D Compiler v2.067.0 on MacOS 
 10.10.3) I had a program with an unexpected behaviour
 and I reduced it to the minimal form below. The error as 
 indicated in the comment is that the function call pvi_calc 
 changes int_1 when I think it should not. The result copied 
 below.

 I hope this helps. Kind regards
 John Nixon


 import std.stdio;
 int n,cp;
 double[] pvi,int_1,int_2;

 void pvi_centre(const int centre){
   int_1=pvi_calc(centre);
   writeln("int_1 = ",int_1);
   int_2=pvi_calc(n-1-centre);//pvi_calc is changing int_1!
   writeln("int_1 = ",int_1);
   return;}

 double[] pvi_calc(const int n1){
   for(int i=0;i<=n1;++i)pvi[i]= 1;
   return pvi;}

 int main(){
   n=10;
   pvi.length=n;
   int_1.length=int_2.length=n;
   pvi_centre(cp);
   return 0;}
 ~

 int_1 = [1, nan, nan, nan, nan, nan, nan, nan, nan, nan]
 int_1 = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
There is only one "pvi" array at all. So, pvi_calc function modifying that only one, and returns it back. When you first call pvi_calc, int_1 points to pvi array. When you call it second time, int_2 points to same pvi array again. Since both of them points to same array, value of int_1 (actually value of pvi array) changes.
Jun 07 2015