Arduino does not understand a ranged FOR loop

The title speaks for itself, but why doesn’t it know what a ranged FOR loop is? Is it going to be available in a future update or is it just not important enough to be implemented?

It is not the arduino it is the GCC compiler, the arduino team just use this compiler.

Oh, alright. They need to upgrade.

What is a ranged FOR loop? Never heard before.

Its an iteration, and sorry, it’s called a Range-based for loop

int array[10] = {0,1,2,3,4,5,6,7,8,9};

for(int out : array) 
{
  Serial.print(out);
}

It should return: 0123456789
It is a feature in C++11, and I thought it would work with the IDE, but nope.

HazardsMind: Is it going to be available in a future update?

You could help move it into a future update. You are running Windows, correct?

yep XP, Vista, and 8

FIY it’s the same as a “foreach” in other languages.

HazardsMind: yep XP, Vista, and 8

• Ensure the Arduino IDE is [u]not[/u] running

• Download this... http://www.atmel.com/tools/ATMELAVRTOOLCHAINFORWINDOWS.aspx

• Install. Mine ended up here...

C:\Program Files (x86)\Atmel\AVR Tools\AVR Toolchain\

• Navigate to the following in your Arduino directory...

{ArduinoInstallRoot}\hardware\tools\

• Rename the[u]avr[/u]directory to[u]avr (old)[/u]

• Create a new directory named[u]avr[/u]

• Navigate to the Atmel AVR Toolchain directory

• Select All

• Cut

• Navigate back to the Arduino[u]avr[/u]directory

• Paste

• Start the Arduino IDE and test

• Report back what you find

HazardsMind:
Its an iteration, and sorry, it’s called a Range-based for loop

int array[10] = {0,1,2,3,4,5,6,7,8,9};

for(int out : array)
{
  Serial.print(out);
}



It should return: 0123456789
It is a feature in C++11, and I thought it would work with the IDE, but nope.

Well, I imagine when the IDE starts distributing a more modern compiler than the 4 year old compiler they are currently distributing, C++11 features will work. But you can always do it via:

int array[10] = {0,1,2,3,4,5,6,7,8,9};

for (size_t i = 0; i < sizeof (array) / sizeof (array[0]); i++)
  {
    int out = array[i];
    Serial.print (out);
  }

MichaelMeissner:
But you can always do it via:

int array[10] = {0,1,2,3,4,5,6,7,8,9};

for (size_t i = 0; i < sizeof (array) / sizeof (array[0]); i++)
  {
    int out = array[i];
    Serial.print (out);
  }

Or…

int array[10] = {0,1,2,3,4,5,6,7,8,9};
int out;

for (size_t i = 0; out = array[i], i < sizeof (array) / sizeof (array[0]); i++)
  {
    Serial.print (out);
  }
for (size_t i = 0; out = array[i], i < sizeof (array) / sizeof (array[0]); i++)

You sure you got that comma in the right place? Doesn’t look right to me.

PaulS:

for (size_t i = 0; out = array[i], i < sizeof (array) / sizeof (array[0]); i++)

You sure you got that comma in the right place? Doesn’t look right to me.

Yup, I’m sure. It’s the “comma operator”. It means “do the left side, then do the right side, and return the value from the right side”.

So, that assigns array[ i ] to out, then does the comparison, and returns the result of the comparison to the for loop.

matt@laptop01:~$ cat test.c
#include <stdio.h>

void main()
{
int array[10] = {0,1,2,3,4,5,6,7,8,9};
int out;
size_t i;

for (i = 0; out = array[i], i < sizeof (array) / sizeof (array[0]); i++)
  {
    printf("%d\n", out);
  }
}
matt@laptop01:~$ cc -o test test.c
matt@laptop01:~$ ./test
0
1
2
3
4
5
6
7
8
9
matt@laptop01:~$

Yea this works.

void setup(){
  Serial.begin(9600);
  int array[10] = {
    0,1,2,3,4,5,6,7,8,9  };
  int out;

  for (size_t i = 0; out = array[i], i < sizeof (array) / sizeof (array[0]); i++)
  {
    Serial.print (out);
  }
}

void loop() {}

0123456789

"simple" for loops can be quite complex and convoluted.

Not many people use that syntax for a for loop, as it's not as intuitive as putting the assignment (or using the iterator variable directly) inside the loop itself.

While it's perfectly valid, it's mainly there as a demonstration of how things in C aren't always what they appear. What you think may be missing in C may just be doable in another way - a not very obvious way.

In general though, for things like that, it's better to be more long winded and do it as specific steps within the loop - that way when you come to look at it again in the morning you know what's going on.

MichaelMeissner: Well, I imagine when the IDE starts distributing a more modern compiler than the 4 year old compiler they are currently distributing, C++11 features will work.

In their defense the "more modern" compiler is noticeably slower.

Comma operator again.

#define A_SIZEOF(ARRAY)     (sizeof(ARRAY) / sizeof(ARRAY[0]))

void loop()
{   }

void setup()
{
    int array[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

    Serial.begin(9600);

    for ( size_t out, i = 0; out = array[i], i < A_SIZEOF(array); i++)
    {
        Serial.print(out);
    }
}

that way when you come to look at it again in the morning you know what’s going on.

Agreed 100%. The only reason I can see for doing it the way you posted was as an entry in an obfuscation contest.

Since the compiler is great at optimizing code, there is no reason not to write clear code, and let the compiler manage the obfuscation.

majenko: "simple" for loops can be quite complex and convoluted.

Not many people use that syntax for a for loop, as it's not as intuitive as putting the assignment (or using the iterator variable directly) inside the loop itself.

Well also, as was mentioned, the ranged syntax is a feature of the new C++ standard. So it depends on whether you are using new compilers (and possibly options to enable the new standards). For example, on my Fedora 17 system, which uses GCC 4.7.2, I have to add the option -std=c++11 or -std=gnu++11 to enable the ranged syntax. My laptop, which is frozen at Fedora 14 due to the graphics chip and uses GCC 4.5.1, does not support -std=gnu++11, and if I use the older form of the switch (-std=gnu++0x), it still doesn't have support for ranged for statements. The GCC released with the IDE is even older (4.3.2 for the Linux distros).

[quote author=Coding Badly link=topic=168152.msg1252380#msg1252380 date=1369442304]

MichaelMeissner: Well, I imagine when the IDE starts distributing a more modern compiler than the 4 year old compiler they are currently distributing, C++11 features will work.

In their defense the "more modern" compiler is noticeably slower.

[/quote]

Do you mean the compile time or emitted instructions. I have been interested in C++11 for a while and heard the new AVR compiler produces more efficient code with things like constexpr and such. Could be wrong though.