Go Down

Topic: Compiler error associated with Switch (using documentation) (Read 945 times) previous topic - next topic

tweedius

Hello,

The compiler was giving me a rather hard to track error, I was getting the dreaded "expected primary-expression before '}' token" error.  I looked through the code 50 times and had all my }'s and ;'s in order.  What I found out is that if you use "default:" without a break; or without some sort of statement that ends in ";" while using the switch() statement you will get this error.

The documentation has commented lines in the example code after the default: label (http://arduino.cc/en/Reference/SwitchCase).  However if you ran the code as is in the example code you would get this same error.

I know this may be minor, but it took me a good deal of time to track down the error until I remembered the comment everything out and then slowly un-comment everything trick.

I hope I have given enough detail and I hope this may be useful, it is getting late and the caffeine isn't helping anymore.  Also, I hope this is the appropriate place to post this, as the reference page led me here.

Thanks.

-Mat

robtillaart

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

tweedius

Sorry for the late reply.  I didn't see this until today.  Here is some code that produces the compiler error:

Error:
Code: [Select]

lightbar.cpp: In member function 'void lightbar::set_led(int, int, int, int)':
lightbar.cpp:81: error: expected primary-expression before '}' token
lightbar.cpp:81: error: expected `;' before '}' token


This code is just a little project I am working on and completely unfinished, but if this is a rare case I wanted to be able to demonstrate it:

Relevant code:
Main sketch:
Code: [Select]


#include "Tlc5940.h"
#include "lightbar.h"

lightbar lightbar;

int counter = 0;
int d = 30;
int r, g, b;

void setup() {

  lightbar.init();

  r = 0;
  g = 0;
  b = 0;

}

void loop() {
 
  for(int i=0; i <=1000; i++){
    lightbar.set_led(0, i, 0, 0);
    lightbar.set_led(1, i, 0, 0);
    lightbar.set_led(2, i, 0, 0);
    lightbar.set_led(3, i, 0, 0);
    lightbar.set_led(4, i, 0, 0);
    delay(d);
  }

  for(int i=1000; i <=1000; i++){
    lightbar.set_led(0, 500, 0, i);
    lightbar.set_led(1, 500, 0, i);
    lightbar.set_led(2, 500, 0, i);
    lightbar.set_led(3, 500, 0, i);
    lightbar.set_led(4, 500, 0, i);
    delay(d);   
  }
  for(int i=1000; i > 0; i--){
    lightbar.set_led(0, i, 0, i);
    lightbar.set_led(1, i, 0, i);
    lightbar.set_led(2, i, 0, i);
    lightbar.set_led(3, i, 0, i);
    lightbar.set_led(4, i, 0, i);
    delay(d);   
  }
  for(int i=0; i <=1000; i++){
    lightbar.set_led(0, 0, i, 0);
    lightbar.set_led(1, 0, i, 0);
    lightbar.set_led(2, 0, i, 0);
    lightbar.set_led(3, 0, i, 0);
    lightbar.set_led(4, 0, i, 0);
    delay(d);
  }

}



lightbar.cpp:
Code: [Select]


#include "Arduino.h"
#include "Tlc5940.h"
#include "lightbar.h"

lightbar::lightbar(){
  //Constructor, empty for now
}

// calls Tlc5940.h init function and clears any values on the chip
void lightbar::init(){

  //initialize tlc(s)
  Tlc.init();
  //reset pins to off
  Tlc.set(0, 0); 
  Tlc.set(1, 0); 
  Tlc.set(2, 0); 
  Tlc.set(3, 0); 
  Tlc.set(4, 0); 
  Tlc.set(5, 0); 
  Tlc.set(6, 0); 
  Tlc.set(7, 0); 
  Tlc.set(8, 0); 
  Tlc.set(9, 0); 
  Tlc.set(10, 0); 
  Tlc.set(11, 0); 
  Tlc.set(12, 0); 
  Tlc.set(13, 0); 
  Tlc.set(14, 0); 
  Tlc.set(15, 0);
  //send data
  Tlc.update();
 
}

void lightbar::set_led(int led, int r, int g, int b){

 
  switch (led) {
 
    case 0:
     
      Tlc.set(0, r);
      Tlc.set(1, b);
      Tlc.set(2, g);
      Tlc.update();
      break;

    case 1:
      Tlc.set(3, r);
      Tlc.set(4, b);
      Tlc.set(5, g);
      Tlc.update();
      break;

    case 2:
      Tlc.set(6, r);
      Tlc.set(7, b);
      Tlc.set(8, g);
      Tlc.update();
      break;

    case 3:
      Tlc.set(9, r);
      Tlc.set(10, b);
      Tlc.set(11, g);
      Tlc.update();
      break;

    case 4:
      Tlc.set(12, r);
      Tlc.set(13, b);
      Tlc.set(14, g);
      Tlc.update();
      break;

    default:
      //Tlc.update();
     
  }

}

void lightbar::set_all(int color){

  //reset pins to off
  Tlc.set(0, color); 
  Tlc.set(1, color); 
  Tlc.set(2, color); 
  Tlc.set(3, color); 
  Tlc.set(4, color); 
  Tlc.set(5, color); 
  Tlc.set(6, color); 
  Tlc.set(7, color); 
  Tlc.set(8, color); 
  Tlc.set(9, color); 
  Tlc.set(10, color); 
  Tlc.set(11, color); 
  Tlc.set(12, color); 
  Tlc.set(13, color); 
  Tlc.set(14, color); 
  Tlc.set(15, color);
  //send data
  Tlc.update();
 
}

void lightbar::clear_all(){

    //reset pins to off
  Tlc.set(0, 0); 
  Tlc.set(1, 0); 
  Tlc.set(2, 0); 
  Tlc.set(3, 0); 
  Tlc.set(4, 0); 
  Tlc.set(5, 0); 
  Tlc.set(6, 0); 
  Tlc.set(7, 0); 
  Tlc.set(8, 0); 
  Tlc.set(9, 0); 
  Tlc.set(10, 0); 
  Tlc.set(11, 0); 
  Tlc.set(12, 0); 
  Tlc.set(13, 0); 
  Tlc.set(14, 0); 
  Tlc.set(15, 0);
  //send data
  Tlc.update();

}


lightbar.h:
Code: [Select]


#ifndef lightbar_h

  #define lightbar_h
  #define MAX_BRIGHTNESS 1023
 
  #include "Arduino.h"
   
  class lightbar
  {
    public:
   
      lightbar();
      void init();
      void set_led(int led, int r, int g, int b);   
      void set_all(int color);
      void clear_all();
   
    private:
     
      //!
   
  };

#endif



Judging by your response, I'm guessing it may not occur in a normal sketch, but my problem may be associated with the switch statement being in a .cpp file?

-Mat

tweedius

Also, if you uncomment the line after the default: label or add break; or any statement that ends with a ';' the error goes away.

pYro_65

I got the same error in my test sketch.
It appears switch cases are labels, so the compiler needs a valid instruction to jump to.

  • Omit the default label.
  • Add a semi colon after it.
  • Add a break.

    I'm still trying to find an exact answer, however other compilers may simply handle this situation by adding their own break;

westfw

gcc definitely doesn't like it, even on an x86 system:

BillW-MacOSX-2<5010> more break.c
#include <stdio.h>
#include <stdlib.h>

int main(int c, char *argv[])
{
    switch(c) {
    case 12: printf("12");
        break;       
    case 99: printf("99");
        break;
    default:
    }
    exit(0);
}
BillW-MacOSX-2<5011> gcc -c99 break.c
break.c: In function 'main':
break.c:12: error: label at end of compound statement

robtillaart

not only switch case labels but any label. Minimal version

Code: [Select]

void setup()
{
  monkey:
  // ;
}

void loop()
{
}
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

pYro_65

Yeah that's why I assumed case labels are actual line labels. I'm pretty sure labels do require source to point to, its other compilers playing nice that are allowing it. However I thought switch was an exception.

It must be because the compiler cannot decide what to do with it. It could point to the implicit compiler generated return, or the explicit next statement outside of the function. However every situation the error occurs is quite illogical and is probably a good hint to change things.

westfw


pYro_65

I'm not sure about labels outside of a switch,  but I have many times commented out the code in a default case to debug my code. This was in visual studio, but I haven't got  a recent version to verify. The OP's post caught my attention as its something I remember doing without error.

Oh, it was all in C++, no C files were used to compile the code.

Go Up