www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Block thinking, and the initialization of variables

reply Christopher Stevenson <Christopher_member pathlink.com> writes:
I tried this foreach statement a little while back to neatly format output:

#int [char[]] aArray;
#aArray["red"]  = 0;
#aArray["blue"] = 1;
#aArray["green] = 2;
#
#foreach(char[] index, int value; aArray)
#{
#     int ctr;
#
#     printf("%.*s = #d", index,value);
#     if (++ctr < aArray.length)
#          printf(", ");
#     else
#          printf("\n");
#}

This little bit of code didn't put out a newline after the last element.  Why?
It reinitialized ctr to 0 for each iteration.  (Yes, I printf-ed to find that
out.)

Is this a bug, or a feature?
(I 'fixed' the code by making ctr static.)

--Chris Stevenson
US Army soldier coding from iraq
Aug 15 2004
next sibling parent reply Nick <Nick_member pathlink.com> writes:
In article <cfn4og$aac$1 digitaldaemon.com>, Christopher Stevenson says...
#foreach(char[] index, int value; aArray)
#{
#     int ctr;
#
#     printf("%.*s = #d", index,value);
#     if (++ctr < aArray.length)
#          printf(", ");
#     else
#          printf("\n");
#}

This little bit of code didn't put out a newline after the last element.  Why?
It reinitialized ctr to 0 for each iteration.  (Yes, I printf-ed to find that
out.)

I believe this is expected behavior. Every time you "enter" the {} code block, ctr is redeclared and is basically a new variable. Be careful with static, are you sure that ctr will be initialized _at all_ next time you call the function? You could put ctr outside the loop, but I think the best solution in this particular case would be to foreach over aArray.keys instead and use an integer index. If ctr wasn't reinitialized the way it is, this could lead to some very hard to read code in more complicated cases, IMHO. Nick
Aug 15 2004
parent reply Deja Augustine <Deja_member pathlink.com> writes:
In article <cfnis6$go4$1 digitaldaemon.com>, Nick says...
In article <cfn4og$aac$1 digitaldaemon.com>, Christopher Stevenson says...
#foreach(char[] index, int value; aArray)
#{
#     int ctr;
#
#     printf("%.*s = #d", index,value);
#     if (++ctr < aArray.length)
#          printf(", ");
#     else
#          printf("\n");
#}

This little bit of code didn't put out a newline after the last element.  Why?
It reinitialized ctr to 0 for each iteration.  (Yes, I printf-ed to find that
out.)

I believe this is expected behavior. Every time you "enter" the {} code block, ctr is redeclared and is basically a new variable. Be careful with static, are you sure that ctr will be initialized _at all_ next time you call the function? You could put ctr outside the loop, but I think the best solution in this particular case would be to foreach over aArray.keys instead and use an integer index. If ctr wasn't reinitialized the way it is, this could lead to some very hard to read code in more complicated cases, IMHO. Nick

While I have yet to implement foreach in D.NET, from looking at the compiler code, it appears that D treats a foreach statement as a nested function and therefore has its own local scope. -Deja
Aug 15 2004
parent Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
Deja Augustine wrote:
 In article <cfnis6$go4$1 digitaldaemon.com>, Nick says...
 
In article <cfn4og$aac$1 digitaldaemon.com>, Christopher Stevenson says...

#foreach(char[] index, int value; aArray)
#{
#     int ctr;
#
#     printf("%.*s = #d", index,value);
#     if (++ctr < aArray.length)
#          printf(", ");
#     else
#          printf("\n");
#}

This little bit of code didn't put out a newline after the last element.  Why?
It reinitialized ctr to 0 for each iteration.  (Yes, I printf-ed to find that
out.)

I believe this is expected behavior. Every time you "enter" the {} code block, ctr is redeclared and is basically a new variable. Be careful with static, are you sure that ctr will be initialized _at all_ next time you call the function? You could put ctr outside the loop, but I think the best solution in this particular case would be to foreach over aArray.keys instead and use an integer index. If ctr wasn't reinitialized the way it is, this could lead to some very hard to read code in more complicated cases, IMHO. Nick

While I have yet to implement foreach in D.NET, from looking at the compiler code, it appears that D treats a foreach statement as a nested function and therefore has its own local scope.

I can't speak for how the compiler does foreach over standard variables, that is surely true for classes which overload opApply(). A delegate is passed to opApply; the delegate is basically the code in your foreach block.
Aug 16 2004
prev sibling parent Sha Chancellor <schancel pacific.net> writes:
In article <cfn4og$aac$1 digitaldaemon.com>,
 Christopher Stevenson <Christopher_member pathlink.com> wrote:

 I tried this foreach statement a little while back to neatly format output:
 
 #int [char[]] aArray;
 #aArray["red"]  = 0;
 #aArray["blue"] = 1;
 #aArray["green] = 2;
 #
 #foreach(char[] index, int value; aArray)
 #{
 #     int ctr;
 #
 #     printf("%.*s = #d", index,value);
 #     if (++ctr < aArray.length)
 #          printf(", ");
 #     else
 #          printf("\n");
 #}
 
 This little bit of code didn't put out a newline after the last element.  Why?
 It reinitialized ctr to 0 for each iteration.  (Yes, I printf-ed to find that
 out.)
 
 Is this a bug, or a feature?
 (I 'fixed' the code by making ctr static.)
 
 --Chris Stevenson
 US Army soldier coding from iraq

Try this in PERL, C with a for() loop or anything else.. It'll happen in them too. That's the desired behavior. Move your declaration. You basically make another copy for every iteration of the loop.
Aug 17 2004