Error with Firmware 2.2.0 control reaches end of non-void function [-Werror=return-type]

Hello
in a remote control sketch I use functions. Up to version 2.1.0 I never received an error message, I wanted to update my Boron with version 2.2.0 but I get the following error for both functions:
remotecontrolmognev1.ino: 122: 5: control reaches end of non-void function [-Werror = return-type].
I am attaching the complete sketch so that we can verify the code.
Thanks
Valentino

// ***** Controllo remoto x Mognenigo con STATO si riceve un "1" o "0" visibile in VB sul Browser *****
#define ON 1
#define OFF 0

int BstartState = 0;
int BStato=0;
int RstartState = 0;
int RStato=0; //
//int trunkState = 0;
//int lockState = 0;

// BOILER
int BSTARTPIN = D0;
int BREADPIN=D1;

// RISC
int RSTARTPIN = D2;
int RREADPIN=D3;
//int LOCKPIN = D5;
//int UNLOCKPIN = D4;

//***Variabili misura temperatura Sonda Wall Wangzi shell
int pinTemp=A0;
int sensorT=0;
double voltT=0;
double Temp=0;

//***Variabili misura Umidita Sonda Wall Wangzi shell
int pinUmi=A1;
int sensorU=0;
double voltU=0;
double Umi=0;

uint32_t UPDATE_INTERVAL = 1000; // in milliseconds
uint32_t FIFTEEN_MINUTES = 60*15*1000; // in milliseconds

// BOILER
uint32_t lastTime = 0; // in milliseconds
uint32_t startTime = 0; // in milliseconds

// RISC
uint32_t RlastTime = 0; // in milliseconds
uint32_t RstartTime = 0; // in milliseconds

void setup() {
    Particle.keepAlive(120);// serve per mantenere il collegamento con il provider telefonia
    Particle.function("Bstart", BstartFunction);
    Particle.variable("Bstartstate", &BstartState, INT);
    Particle.variable("BStato",BStato);
    
    Particle.function("Rstart", RstartFunction);
    Particle.variable("Rstartstate", &RstartState, INT);
    Particle.variable("RStato",RStato);
    
    pinMode(BSTARTPIN,OUTPUT);
    pinMode(BREADPIN,INPUT_PULLDOWN);
    digitalWrite(BSTARTPIN,LOW);
    digitalWrite(RSTARTPIN,LOW);
    
    pinMode(RSTARTPIN,OUTPUT);
    pinMode(RREADPIN,INPUT_PULLDOWN);
}

void loop() {
    
    //***Calcolo Dati Temperatura Sonda Wall Wangzi shell
    sensorT = analogRead(pinTemp);
    voltT = (3.3 * sensorT) / 4095.0;
    Temp=-40 + (120/0.016)*(voltT/160 - 0.0038);// Per le spiegazioni calcolo vedi inizio skecht//Impostazione origine 0.004//impost.23.10.2020 ->0.0042
    //Serial.print(sensorT);Serial.print(" ");Serial.print(voltT);Serial.print(" ");Serial.println(Temp);

//***Calcolo Dati Umidita Sonda Wall Wangzi shell
    sensorU = analogRead(pinUmi);
    voltU = (3.3 * sensorU) / 4095.0;
    Umi=(100/0.016)*(voltU/160 - 0.0042); // Impostazione origine 0.004
    Serial.print(sensorU);Serial.print(" ");Serial.print(voltU);Serial.print(" ");Serial.println(Umi);
        
//Publish Tem&Umidita Sonda Wall Wangzi shell
    char tdata[32];
    //snprintf(tdata, sizeof(tdata), "temp:%.1f,umi:%.1f", Temp, Umi);
    snprintf(tdata, sizeof(tdata), "temp:%.2f,umi:%.2f", Temp, Umi);
    Particle.publish("dhtData",tdata, PRIVATE);
    //Particle.publish("dhtData",tdata, PUBLIC);
    Serial.print("Temp:");Serial.print(Temp);Serial.print(" ");Serial.print("Umi:");Serial.println(Umi);
    delay(1000);    
    BStato=digitalRead(BREADPIN);
    Serial.print("Boiler: ");Serial.println(BStato);
    RStato=digitalRead(RREADPIN);
    Serial.print("RISC: ");Serial.println(RStato);
    delay(5000);
    }     
    // ********************************************************
    //**** BOILER **** // 
    // ********************************************************
    int BstartFunction(String args)
    {
    if(BstartState == OFF)
    {
        BstartState = ON; // engine started
        //startTime = millis(); // Modifica 02062019
        digitalWrite(BSTARTPIN, HIGH); // Double press the start button to start
        //Stato=digitalRead(READPIN); // Modifica 02062019
    return 200; // This is checked in the web app controller for validation
    }
    else if (BstartState == ON)
    {
        BstartState = OFF; // engine stopped
        //digitalWrite(STARTPIN, HIGH); // Modifica 02062019 // Single press the start button to stop
        //delay(500);// Modifica 02062019
        digitalWrite(BSTARTPIN, LOW); // Modifica 02062019
        //Stato=digitalRead(READPIN);
    return 200; // This is checked in the web app controller for validation
    }
    }

    // ********************************************************
    //**** RISC **** // Update the filter every 10ms (default)
    // ********************************************************
    
    int RstartFunction(String args)
    {
    if(RstartState == OFF) {
        RstartState = ON; // engine started
        //startTime = millis(); // Modifica 02062019
        digitalWrite(RSTARTPIN, HIGH); // Double press the start button to start
        //Stato=digitalRead(READPIN); // Modifica 02062019
    return 200; // This is checked in the web app controller for validation
    }
    else if (RstartState == ON)
    {
        RstartState = OFF; // engine stopped
        //digitalWrite(STARTPIN, HIGH); // Modifica 02062019 // Single press the start button to stop
        //delay(500);// Modifica 02062019
        digitalWrite(RSTARTPIN, LOW); // Modifica 02062019
        //Stato=digitalRead(READPIN);
    return 200; // This is checked in the web app controller for validation
    }
    }

You need to consider all possible code paths in a function
e.g.

Here you have only two “business cases” covered but nothing prevents BstartState from being anything other that the allowed values OFF (0) and ON (1).
And hence the compiler will flag this as an error (now).
In previous versions this would still have been a bug, but not been flagged by the compiler.

BTW, since both your code paths return the same value, why would you have separate return statements?

I’d rather write it this way

int BstartFunction(String args) {
  switch (BstartState) {
    case OFF:  
        // off treatment
        break;

    case ON:
      // on treatment
      break;

    default:
      return -1; // some return value that indicates an error
  }

  return 200;   // This is checked in the web app controller for validation
}

This way each and every code path will have a valid return statement.

8 Likes

Thanks @ScruffR now it works I think it is even more elegant to use swicht case.
Best Regards Valentino

2 Likes

Does this change only affect web functions? Do I need an else statement with all If commands or just those with an if/else path? Thanks for any guidance.

You do need to have a return statement in every code path that leaves any non-void function - irrespective whether it’s conditional or not.

That has always been the case, that rule just wasn’t enforced by the compiler before.

1 Like