Problem: 'else' without a previous 'if'

Hello, everyone

I'm working on my first project and I've encountered an issue called "else" without a previous "if".

Here's my code:

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);

const int beeperPin = 2;
int beeperIntervallBackRight;
int beeperIntervallBackLeft;
const int maxDistanceForBeeper = 60; //distance needs to be reviewed
const int minDistanceForBeeper = 2; //distance needs to be reviewed
const int maxValForBeeperIntervall = 110;
const int minValForBeeperIntervall = 10;

const int ledPin = 3;

const int motorTempPin = A0;
int motorTemp;
float motorTempSensorVal;
const int motorTempTooHigh = 50; //Temp needs to be checked
const int motorTempTooLow = -5; //Temp needs to be checked

const int batteryTempPin = A1;
int batteryTemp;
float batteryTempSensorVal;
float batteryTempSensorValRaw; //(datatype float)needs to be checked
const int batteryTempTooHigh = 50;
const int batteryTempTooLow = -5;

const int trigPinBackRight = 4;
const int echoPinBackRight = 5;
long durationBackRight;
float distanceBackRightCm;
float distanceBackRightM;

const int trigPinBackLeft = 6;
const int echoPinBackLeft = 7;
long durationBackLeft;
float distanceBackLeftCm;
float distanceBackLeftM;

const int casBackSwitchPin = 8;
int casBackSwitchState; //needs to be ckecked(could be( = 0))

const int brakePin = 9;
const int maxDistanceForBrake = 150;//distance needs to be reviwed

unsigned long previousTime; //needs to be ckecked(could be( = 0))
unsigned long currentTime;

void setup() {

  lcd.begin();
  lcd.backlight();
           
  lcd.setCursor(0,0);
  lcd.print("casBackRight: ");
  lcd.setCursor(0,1);
  lcd.print("casBackLeft: ");
    
  lcd.setCursor(0,2);
  lcd.print("motorTemp: ");
  lcd.setCursor(0,3);
  lcd.print("batteryTemp: ");

  
  pinMode(beeperPin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(trigPinBackRight, OUTPUT);
  pinMode(echoPinBackRight, INPUT);
  pinMode(trigPinBackLeft, OUTPUT);
  pinMode(echoPinBackLeft, INPUT);
  pinMode(casBackSwitchPin, INPUT);
  pinMode(brakePin, OUTPUT);

  
}

void loop() {

  casBackSwitchState = digitalRead(casBackSwitchPin);
  currentTime = millis();

  if(casBackSwitchState == HIGH); {
    
    digitalWrite(trigPinBackRight, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPinBackRight, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPinBackRight, LOW);
    durationBackRight = pulseIn(echoPinBackRight, HIGH);
    distanceBackRightCm = durationBackRight * 0.034 / 2;
    if(distanceBackRightCm <= 400) {
      distanceBackRightM = (distanceBackRightCm / 100.00);
    }
    
    digitalWrite(trigPinBackLeft, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPinBackLeft, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPinBackLeft, LOW);
    durationBackLeft = pulseIn(echoPinBackLeft, HIGH);
    distanceBackLeftCm = durationBackLeft * 0.034 / 2;
    if(distanceBackLeftCm <= 400) {
      distanceBackLeftM = (distanceBackLeftCm / 100.00);
    }
    
    if(distanceBackRightCm <= maxDistanceForBeeper || distanceBackLeftCm <= maxDistanceForBeeper) {

     constrain(distanceBackRightCm, minDistanceForBeeper, maxDistanceForBeeper);
     int beeperIntervallBackRight = map(distanceBackRightCm, minDistanceForBeeper, maxDistanceForBeeper, minValForBeeperIntervall, maxValForBeeperIntervall);  
     constrain(distanceBackLeftCm, minDistanceForBeeper, maxDistanceForBeeper);
     int beeperIntervallBackLeft = map(distanceBackLeftCm, minDistanceForBeeper, maxDistanceForBeeper, minValForBeeperIntervall, maxValForBeeperIntervall);

     if(distanceBackRightCm <= distanceBackLeftCm) {

      if(currentTime - previousTime >= beeperIntervallBackRight) {
        digitalWrite(beeperPin, HIGH);
        if(currentTime - previousTime >= (beeperIntervallBackRight * 2)) {
          digitalWrite(2, LOW);
          previousTime = currentTime;
        }
      }
     }

     else if(distanceBackRightCm > distanceBackLeftCm) {
      
      if(currentTime - previousTime >= beeperIntervallBackLeft) {
        digitalWrite(beeperPin, HIGH);
        if(currentTime - previousTime >= (beeperIntervallBackLeft * 2)) {
          digitalWrite(2, LOW);
          previousTime = currentTime;
        }
      }
     }
    }

    else {
      digitalWrite(beeperPin, LOW);
    }

    if(distanceBackRightCm <= maxDistanceForBrake || distanceBackLeftCm <= maxDistanceForBrake) {
      digitalWrite(brakePin, HIGH);
    }
    else {
      digitalWrite(brakePin, LOW);
    }
        
    lcd.setCursor(14,0);
    lcd.print(distanceBackRightM);
    lcd.setCursor(18,0);
    lcd.print("m");

    lcd.setCursor(14,1);
    lcd.print(distanceBackLeftM);
    lcd.setCursor(18,1);
    lcd.print("m");
    
  }
  else {
    
    digitalWrite(beeperPin, LOW);
    digitalWrite(brakePin, LOW);
    
    lcd.setCursor(14,0);
    lcd.print("!OFF!");

    lcd.setCursor(14,1);
    lcd.print("!OFF!");
    
  }
  
  motorTempSensorVal = analogRead(A0);
  motorTemp = (motorTempSensorVal) * 0.48848125;

  batteryTempSensorValRaw = analogRead(A1);
  batteryTempSensorVal = (batteryTempSensorValRaw / 1024.0) * 5.0;
  batteryTemp = (batteryTempSensorVal - 0.5) * 100; //Might be .5 instead of 0.5(kit)
   
  lcd.setCursor(16,2);
  lcd.print(motorTemp);

  if(motorTemp >= motorTempTooHigh) {
    digitalWrite(ledPin, HIGH);       
    lcd.setCursor(18,2);
    lcd.print("!");
  }
  else if(motorTemp <= motorTempTooLow) {
    digitalWrite(ledPin, HIGH);  
    lcd.setCursor(18,2);
    lcd.print("!");
  }
  else { 
    digitalWrite(ledPin, LOW);       
    lcd.setCursor(18,2);
    lcd.print("C");
  }
  
  lcd.setCursor(16,3);
  lcd.print(batteryTemp);
  
  if(batteryTemp >= batteryTempTooHigh) {
    digitalWrite(ledPin, HIGH);      
    lcd.setCursor(18,3);
    lcd.print("!");
  }
  else if(batteryTemp <= batteryTempTooLow) {
    digitalWrite(ledPin, HIGH);     
    lcd.setCursor(18,3);
    lcd.print("!");
  }
  else {
    digitalWrite(ledPin, LOW);
    lcd.setCursor(18,3);
    lcd.print("C");
  }
}
if(casBackSwitchState == HIGH); {

Remove the semicolon.

(Also, use code formatting next time.)

1 Like

Read the forum guidelines to see how to properly post code and some good information on making a good post.
Use the IDE autoformat tool (ctrl-t or Tools, Auto format) before posting code in code tags.

You can go back and fix your original post by highlighting the code and clicking the </> in the menu bar.
code tags new

Thats right. if the semicolon is present then that if will always return true.

I fixed that a bit for you.

a7

1 Like

Actually you are right. The condition will not be checked but the block of code that the if statement would execute, will aleays be executed no matter what.
I think older versions of arduino ide would pass such code without giving the else without if error

Almost…
The condition WILL be checked, but there’s nothing to execute.
The following { } block is just a standalone block of code. Nothing to do with the if () statement.

While I'm sure that this is closer to the truth than HellasT's explanation, I wouldn't be surprised if there are compilers that will just optimize the condition away entirely because it is irrelevant.

Then again, I don't understand why any compiler even allows the "if(condition);" antipattern.

I m pretty sure that if a compiler allows such error then the code will be executed as if that if statement was true. I cant think of a compiler that would allow it right now but if someone knows of any then i would be happy to give it a try :slight_smile:
Bottom line : Its a mistake and can only ruin a code.

If you write something like this

if(condition); {
    doStuff();
}

according to official C/C++ syntax, the only thing that is affected by the condition is everything between the ) and the semicolon. I. e. - nothing.

The "doStuff()" will be executed regardless of the condition, because C/C++ (and Java, in fact) just let you wrap stuff in {} brackets whenever you feel like it.

But again - there is no reason why you'd ever want to actually write something like that. If it is present in any bit of code, it is almost guaranteed to be an error.

Only goes to show that an IDE for beginners needs a good linter, even more than an IDE for pros.

1 Like

In this case no matter, but the expression could have side effects, thus need evaluation.

But it is stupid to hide such a thing in a useless if.

a7

Right.

But if I want the side effects of "aMethodThatDoesStuff();", I write "aMethodThatDoesStuff();", not "if(aMethodThatDoesStuff());". I don't think there's any reason why anybody would ever write the latter on purpose.

Yes.

The only thing I can think of is someone smart enough to know about short circuit evaluation but so dumb as to think it only happens inside a test that's part of an if or while statement…

Wel not dumb, ignorant.

a7

Thank You for helping, this must have happened while i copied the code from a previous version.

With "Compiler warnings" set to "All", you'll get a warning for the empty if body:

/home/c/Arduino/sketch_may12a/sketch_may12a.ino: In function 'void setup()':
/home/c/Arduino/sketch_may12a/sketch_may12a.ino:4:11: warning: suggest braces around empty body in an 'if' statement [-Wempty-body]
 if (true);
          ^

Sometimes it is easier to write the inverted condition, i.e.

if(condition == true);
else doFoo();

than it is to write the condition, i.e.

if (condition == true) doFoo();

@Perehama if there were bars where bets were made on stuff like that, I would have lost.

And though I am a fan of eliminating ink wherever I can (no braces if they are not syntactically necesssary, e.g.), here's one case where I would probably use { } as my empty statement!

File under "did learn something or was reminded of it today". :expressionless: THX.

a7

I understand. When this rare use condition occurs, I often append "// do nothing"

I can't be the first to think this, and I am no pro at using the preprocessor, so these may break easily, but appear to work:

# include <stdio.h>

# define unless(x)  if(!(x))

# define until(x)   while(!(x))

int main()
{
    printf("Hello World\n");
    
    int a, b;
    
    a = 12; b = 13;
    
    unless (a == b) printf("...not equal\n");
    
    until (a == 0) {
        printf("%d\n", a);
        a--;
    }

    return 0;
}

TBC I do not recommend using them, just wanted to see if. :wink:

a7

You could go all the way and re-implement your favorite language like S. R. Bourne did in the 1970s: https://minnie.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/sh/mac.h. Example usage (from cmd.c in the same source tree):

	IF sym&SYMFLG
	THEN	REG SYSPTR	sp=reserved;
		WHILE sp->sysval
			ANDF sp->sysval!=sym
		DO sp++ OD
		prs(sp->sysnam);
	ELIF sym==EOFSYM
	THEN	prs(endoffile);
	ELSE	IF sym&SYMREP THEN prc(sym) FI
		IF sym==NL
		THEN	prs("newline");
		ELSE	prc(sym);
		FI
	FI

I also wouldn't recommend it, but it might be good for the IOCCC.