Go Down

Topic: name lookup of 'i' changed for new ISO 'for' scoping (Read 7980 times) previous topic - next topic

nanohex

I've written a simple brushless motor testing program, but i'm getting a weird error I've never seen before  :smiley-eek-blue:!

What does this error mean and how do I fix it? Thanks in advance!
BTW the error happens somewhere in the for loop where 'i' is between 1500 and 1000 I think. The code works fine up till that point.

Code: [Select]
#include <LiquidCrystal.h>
#include <Servo.h> //Notice how you can use the standard servo library!

Servo bldc_motor; //creates a "servo" object (the ESC and motor)
LiquidCrystal LCD (2, 3, 4, 5, 6, 7); ///create an LCD


void setup()
{
  bldc_motor.attach (9); //attach the motor to pin 9
  LCD.begin (16, 2); //initialise the LCD
  LCD.clear();
}

void loop()
{
  bldc_motor.writeMicroseconds(1500); //provides a "neutral" pulse. The ESC won't start without this.
  LCD.print ("BLDC Motor Test");
  LCD.setCursor (0, 1);
  LCD.print ("Starting in ");
 
  for (int i = 4; i >= 0; i --) //countdown timer
  {
    LCD.setCursor (12, 1);
    LCD.print (i+1);
    LCD.print ("s");
    delay (1000);
  }
 
  LCD.setCursor (0, 1);
  LCD.print ("                "); //clears the bottom line of the LCD
 
  LCD.setCursor (5, 1);
  LCD.print ("forward"); //writing it here so it doesn't keep rewriting this in the for loop
 
  while(1)
  {
    for (int i = 1500; i <= 2000; i++)
    {
      int speed_value = map (i, 1500, 2000, 0, 100); //maps the signal pulse to a percentage
      LCD.setCursor (0, 1);
      LCD.print ("   "); //clears any previous number;
      LCD.setCursor (0, 1);
      LCD.print (speed_value); //prints the percentage to the LCD
      LCD.print ('%'); //notice the single quotation marks. I've just sent a char value, not a string because it's only 1 character
     
      bldc_motor.writeMicroseconds (i); //actually write the value to the motor
      delay(10);// small delay so you can see what's happening
    }
   
    LCD.setCursor (0, 1);
    LCD.print ("                "); // clears the bottom of the LCD screen;
    LCD.setCursor (0, 1);
    LCD.print ("braking in");
   
    for (int i = 4; i >= 0; i --) //countdown timer
    {
      LCD.setCursor (12, 1);
      LCD.print (i+1);
      LCD.print ("s");
      delay (1000);
    }
   
    bldc_motor.writeMicroseconds (1000); //full reverse. The ESC will automatically brake the motor.
    delay (500); //small delay to let things happen
    bldc_motor.writeMicroseconds (1500); //give a neutral signal
    LCD.setCursor (0, 1);
    LCD.print ("motor stopped");
    delay (3000); //keep it that way for a while
   
    LCD.setCursor (0, 1);
    LCD.print ("                "); //clear the bottom line of the LCD
    LCD.setCursor (5, 1);
    LCD.print ("backward");
   
    for (int i = 1500; i >= 1000; i --);
    {
      int speed_value = map (i, 1500, 1000, 0, 100); //maps the signal pulse to a percentage
      LCD.setCursor (0, 1);
      LCD.print ("   "); //clears any previous number;
      LCD.setCursor (0, 1);
      LCD.print (speed_value); //prints the percentage to the LCD
      LCD.print ('%'); //notice the single quotation marks. I've just sent a char value, not a string because it's only 1 character
     
      bldc_motor.writeMicroseconds (i); //actually write the value to the motor
      delay(10);// small delay so you can see what's happening
    }
   
    LCD.setCursor (0, 1);
    LCD.print ("                "); //clear bottom line of LCD
   
    bldc_motor.writeMicroseconds (1500);
    LCD.setCursor (0, 1);
    LCD.print ("motor stopped");
    delay (3000);   
  }
     
   
 
}



Error messages:

name lookup of 'i' changed for new ISO 'for' scoping


sketch_nov03a.cpp: error: In funcion 'void loop()':
sketch_nov03a:77: error: name lookup of 'i' changed for new ISO 'for' scoping
sketch_nov03a:37: error: using obsolete binding at 'i' (what on earth does this mean too?)

Nick Gammon

Add a declaration for "i" after loop, eg.

Code: [Select]

void loop()
{
  int i;



Then remove the multiple declarations of "i" elsewhere, eg.

Change:

Code: [Select]

  for (int i = 4; i >= 0; i --) //countdown timer


to:

Code: [Select]

  for (i = 4; i >= 0; i --) //countdown timer



Effectively it is warning you about multiple redeclarations of "i".
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

stimmer

Code: [Select]
    for (int i = 1500; i >= 1000; i --);
    {

You've accidentally put a ; after the for line.
Due VGA library - http://arduino.cc/forum/index.php/topic,150517.0.html

PaulS

Quote
You've accidentally put a ; after the for line.

and then referencing i after the end of the for loop, which isn't allowed.

nanohex

Ah, thanks! That stray semicolon really gave me a headache  :smiley-roll-sweat:

dc42

Any decent C++ compiler will warn about that stray semicolon, but unfortunately the Arduino IDE turns most of the gcc compiler warnings off.
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Nick Gammon

Well spotted, PaulS!

Older versions of the compiler would allow the "i" declared in the loop to remain in scope, so it would be valid to do this:

Code: [Select]

void setup ()
  {
  for (int i = 0; i < 42; i++)
    {
    // whatever
    }
 
  int j = i;      // <------ now raises an error
  }  // end of setup
 
void loop ()  {    }  // end of loop


However more recently "i" is scoped to the loop only, and thus the assignment to "j" fails.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

majenko

Quote
Any decent C++ compiler will warn about that stray semicolon, but unfortunately the Arduino IDE turns most of the gcc compiler warnings off.


Why?  That's a perfectly valid thing to do, and I do it often.  Especially when traversing to the end of a linked list:

Code: [Select]

for(ptr=head; ptr->next; ptr=ptr->next);
ptr->next = newelement;

PaulS

Quote
That's a perfectly valid thing to do, and I do it often.  Especially when traversing to the end of a linked list

Wouldn't it be easier and faster to keep a pointer to tail?

majenko


Quote
That's a perfectly valid thing to do, and I do it often.  Especially when traversing to the end of a linked list

Wouldn't it be easier and faster to keep a pointer to tail?

faster?  yes.  easier?  no.

You have to always ensure you update said pointer every time to add something to the tail.  It just takes one moment of forgetfulness when you don't add the tail pointer updating, and you have a rather nasty bug.  Memory-leaks-r-us.

PaulS

Quote
faster?  yes.  easier?  no.

I'll take your word for it. I've never bothered with singly linked lists. Very little extra memory and effort is required to create doubly linked lists that can then be traversed in either direction. With doubly linked lists, you don't have the luxury of forgetfulness.

Nick Gammon

Standard Template Library.

Then you don't have to re-invent the wheel every time you want a linked list for a different data type.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

majenko


Standard Template Library.

Then you don't have to re-invent the wheel every time you want a linked list for a different data type.

Fine if you want to use C++ I guess.  Not if you either can't or don't want to.

stimmer


Quote
Any decent C++ compiler will warn about that stray semicolon, but unfortunately the Arduino IDE turns most of the gcc compiler warnings off.


Why?  That's a perfectly valid thing to do, and I do it often.  Especially when traversing to the end of a linked list:

Code: [Select]

for(ptr=head; ptr->next; ptr=ptr->next);
ptr->next = newelement;



Yes but have you ever intentionally written for(LinkedList * ptr=head; ptr->next; ptr=ptr->next); and then immediately followed it with a { ?

As far as I know there is no GCC warning for this kind of mistake anyway.
Due VGA library - http://arduino.cc/forum/index.php/topic,150517.0.html

majenko



Quote
Any decent C++ compiler will warn about that stray semicolon, but unfortunately the Arduino IDE turns most of the gcc compiler warnings off.


Why?  That's a perfectly valid thing to do, and I do it often.  Especially when traversing to the end of a linked list:

Code: [Select]

for(ptr=head; ptr->next; ptr=ptr->next);
ptr->next = newelement;



Yes but have you ever intentionally written for(LinkedList * ptr=head; ptr->next; ptr=ptr->next); and then immediately followed it with a { ?

As far as I know there is no GCC warning for this kind of mistake anyway.


Can't say as I have, no, however there is no syntactical reason why that would be wrong.

There is nothing to say that a { HAS to follow a for/while/if etc - it can just be on its own.  You can use it to group blocks of code to make it easier to read.  I don't know anyone that actually does that, but it's perfectly valid.

Go Up