[NXC] ArrayInit for 2D arrays

Discussion specific to NXT-G, NXC, NBC, RobotC, Lejos, and more.
muntoo
Posts: 834
Joined: 01 Oct 2010, 02:54
Location: Your Worst Nightmare
Contact:

Re: [NXC] ArrayInit for 2D arrays

Post 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;}
Image

Commit to LEGO Mindstorms Robotics Stack Exchange:
bit.ly/MindstormsSE


Commit to LEGO Stack Exchange: bit.ly/Area51LEGOcommit
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: [NXC] ArrayInit for 2D arrays

Post 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
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: [NXC] ArrayInit for 2D arrays

Post by afanofosc »

A possible workaround for this compiler bug is to ## append the type to the variable name you are using.

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
muntoo
Posts: 834
Joined: 01 Oct 2010, 02:54
Location: Your Worst Nightmare
Contact:

Re: [NXC] ArrayInit for 2D arrays

Post 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[].
Image

Commit to LEGO Mindstorms Robotics Stack Exchange:
bit.ly/MindstormsSE


Commit to LEGO Stack Exchange: bit.ly/Area51LEGOcommit
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: [NXC] ArrayInit for 2D arrays

Post 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?
muntoo
Posts: 834
Joined: 01 Oct 2010, 02:54
Location: Your Worst Nightmare
Contact:

Re: [NXC] ArrayInit for 2D arrays

Post 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;}
Image

Commit to LEGO Mindstorms Robotics Stack Exchange:
bit.ly/MindstormsSE


Commit to LEGO Stack Exchange: bit.ly/Area51LEGOcommit
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: [NXC] ArrayInit for 2D arrays

Post 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
Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests