Page 3 of 3

Re: [NXC] ArrayInit for 2D arrays

Posted: 05 Jun 2011, 18:49
by muntoo
Looks like a bug in the compiler.
This:

Code: Select all

#define ArrayInitD2(type,arr,val,arrlen1,arrlen2) while(1) {type arrtemp[]; ArrayInit(arrtemp,val,arrlen2); ArrayInit(arr,arrtemp,arrlen1); break;}

task main()
{
  int myBar[][];
  float myFoo[][];
  ArrayInitD2(int, myBar, 123, 10, 20)
  ArrayInitD2(float, myFoo, 12.34, 8, 16)
  
  // some random array readings
  NumOut(0,56, myBar[0][0]);
  NumOut(0,48, myBar[5][5]);
  NumOut(0,40, myBar[9][19]);
  NumOut(0,32, myFoo[3][0]);
  NumOut(0,24, myFoo[7][15]);
  
  while(1);
}
Expands to:

Code: Select all

#define ArrayInitD2(type,arr,val,arrlen1,arrlen2) while(1) {type arrtemp[]; ArrayInit(arrtemp,val,arrlen2); ArrayInit(arr,arrtemp,arrlen1); break;}

task main()
{
  int myBar[][];
  float myFoo[][];
  while(1) {int arrtemp[]; ArrayInit(arrtemp,123,20); ArrayInit(myBar,arrtemp,10); break;}
  while(1) {float arrtemp[]; ArrayInit(arrtemp,12.34,16); ArrayInit(myFoo,arrtemp,8); break;}

  // some random array readings
  NumOut(0,56, myBar[0][0]);
  NumOut(0,48, myBar[5][5]);
  NumOut(0,40, myBar[9][19]);
  NumOut(0,32, myFoo[3][0]);
  NumOut(0,24, myFoo[7][15]);
  
  while(1);
}
See the "redeclaration" of arrtemp as a float[] on line 8?

Using for doesn't help either:

Code: Select all

#define ArrayInitD2(type,arr,val,arrlen1,arrlen2) for(type arrtemp[]; 1; ) {ArrayInit(arrtemp,val,arrlen2); ArrayInit(arr,arrtemp,arrlen1); break;}

Re: [NXC] ArrayInit for 2D arrays

Posted: 06 Jun 2011, 01:54
by afanofosc
I recently reported on these forums that the compiler currently has a bug that makes it impossible to declare a variable with the same name at the same scoping level with two different types, i.e, int foo; float foo; both nested at the same scoping level (obviously in separate scopes). You will have to live with that bug for a while since my local variable decoration scheme does not currently include the variable type and adding that bit of information to the decoration scheme will be non-trivial. Sorry about that!

I would recommend against using these kind of macros as they obscure the fact that you are allocating memory for a temporary array that does not need to remain allocated after that temporary variable is used to allocate memory for the next higher dimension-ed array.

Code: Select all

  int tmp[];
  int myarray[][];
  ArrayInit(tmp, 0, 1000); // 1000 zeros in tmp
  ArrayInit(myarray, tmp, 20); // 20 arrays containing 1000 zeros
  // tmp is no longer needed so a clever programmer will free its memory
  ArrayInit(tmp, 0, 0); // free up that 2k bytes 
So if you are going to wrap trivial code in confusing macros then at least add a line to empty out the temporary arrays.

John Hansen

Re: [NXC] ArrayInit for 2D arrays

Posted: 06 Jun 2011, 01:55
by afanofosc
A possible workaround for this compiler bug is to ## append the type to the variable name you are using.

John Hansen

Re: [NXC] ArrayInit for 2D arrays

Posted: 06 Jun 2011, 04:30
by muntoo
afanofosc wrote:A possible workaround for this compiler bug is to ## append the type to the variable name you are using.

John Hansen
I thought about that. But what about type == unsigned int? Then, we get, unsigned int arrtemp_unsigned int[].

Re: [NXC] ArrayInit for 2D arrays

Posted: 06 Jun 2011, 06:20
by HaWe
afanofosc wrote:A possible workaround for this compiler bug is to ## append the type to the variable name you are using.
John Hansen
what's the syntax like?

Re: [NXC] ArrayInit for 2D arrays

Posted: 06 Jun 2011, 07:15
by muntoo
doc-helmut wrote:what's the syntax like?
Look here.

Code: Select all

#define ArrayInitD2(type,arr,val,arrlen1,arrlen2) while(1) {type arrtemp_##type[]; ArrayInit(arrtemp,val,arrlen2); ArrayInit(arr,arrtemp,arrlen1); break;}

Re: [NXC] ArrayInit for 2D arrays

Posted: 06 Jun 2011, 07:25
by HaWe
#define ArrayInitD2(type,arr,val,arrlen1,arrlen2) while(1) {type arrtemp_##type[]; ArrayInit(arrtemp,val,arrlen2); ArrayInit(arr,arrtemp,arrlen1); break;}
thx!
if you're already passing ##type in the 2nd argument is it possible then to sacrifice passing "type" as the 1st argument?
instead of
ArrayInitD2(int,myArray##int,12345,10,20) // correct?
just
ArrayInitD2(array##int,12345,10,20)
?

ps
of course the macro has to evalute ##int in order to extract the "int type" to use it for the temp variable