CompilerWarnung wegen return?

Hallo zusammen,

wenn ich diese 2 Funktionen Compiliere bekomme ich untenstehende CompilerWarnung.
Wie muss ich das Umschreiben, dasmit ich das ohne Warnung compiliert bekomme?

#define DELAY_BETWEEN_INGREDIENTS 300

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

void pour(String input) {
  int count = 0; // Pour counter
  int times = 0; // Times to pour
  int holdDuration = 0; // Time duration to hold dispenser in open position
  int waitDuration = 0; // Time duration to wait till next pour

  for (uint16_t z = 0; z < input.length(); z++) {
    byte parameter = input.substring(z, z + 1).charAt(0);

    switch (parameter) {
      case 'F':
        times = getParameterValue(input, z);
        break;
      case 'H':
        holdDuration = getParameterValue(input, z);
        break;
      case 'W':
        waitDuration = getParameterValue(input, z);
        break;
    }
  }

  if (holdDuration > 0 && waitDuration > 0) {
    for (int i = 0; i < times; i++) {
//      maestro.setSpeed(0, SERVO_RAISE_SPEED);
//      maestro.setTarget(0, SERVO_MAX_POS);
      delay(holdDuration);
//      maestro.setSpeed(0, SERVO_RELEASE_SPEED);
//      maestro.setTarget(0, SERVO_MIN_POS);
      if (times - 1 > count) {
        delay(waitDuration);
      } else {
        delay(DELAY_BETWEEN_INGREDIENTS);
      }
      count++;
    }
  } else {
    Serial.println("Hold and wait duration parameters cannot be lower than or equal to 0");
  }
}
//---------------------------------pour() ende------------------------------

int getParameterValue(String input, int z) {
  for (uint16_t y = z + 1; y < input.length(); y++) {
    if (input.substring(y, y + 1) == " ") {
      return input.substring(z + 1, y).toInt();
      break;
    }
    if (y == input.length() - 1) {
      return input.substring(z + 1, y + 1).toInt();
    }
  }
}
//------------int getParameterValue() end-------------------------------------

und hier die Warnung des Compilers:

C:\Users\desit\Documents\Arduino\Sketchbook\sketch_sep20a\sketch_sep20a.ino: In function 'int getParameterValue(String, int)':

C:\Users\desit\Documents\Arduino\Sketchbook\sketch_sep20a\sketch_sep20a.ino:65:1: warning: control reaches end of non-void function [-Wreturn-type]

 }

 ^

Der Code läuft (im Ganzen) aber trotz Warnung.
Der Codeschnippsel ist dennoch compilierbar.

Danke.

LG Stefan

Der Codeschnippsel ist dennoch compilierbar.

Es ist ja auch nur eine Warnung und kein Fehler. Aber hast du schonmal was von undefiniertem Verhalten gehört? Der Fall wo das schief geht tritt bei dir vielleicht nie ein. Aber richtig ist es trotzdem nicht

Die Funktion gibt nicht in allen Zweigen etwas zurück. Du kannst -1 zurückgeben wenn keine der Bedingungen zutrifft

Außerdem:

int getParameterValue(String input, int z)

Objekte übergibt man nicht als Kopie. Richtig geht es so:

int getParameterValue(String& input, int z)

Serenifly:
Es ist ja auch nur eine Warnung und kein Fehler.

Auch Warnungen sind meiner Meinung nach Grund genug, Code zu verbessern. Ich halte das für guten Stil. Schon gucken zu müssen, ob etwas ein echter Fehler oder „nur“ eine Warnung ist, finde ich nervig, weil es ablenkt.

Stilfragen sind allerdings nicht jedermanns Sache.

Gruß

Gregor

Klar sollte man es ausbessern. Es gibt auch Warnungen die eigentlich schon Fehler sind, in dem Sinne das der Code nicht richtig laufen kann. Ich meinte nur dass man sich nicht wundern muss wenn es trotzdem compiliert.

Deltaflyer: ...warning: control reaches end of non-void function [-Wreturn-type]

Wenn es Dir nur um eine Quick-and-dirty-Verbesserung geht: Trage am Ende der betreffenden Funktion ein return(0); ein. Dann wird zumindest wie verlangt etwas zurückgegeben. Ansonsten: Ändere bei der Funktionsdefinition das int in void.

Gruß

Gregor

void geht nicht. Er will ja was zurückgeben. Und falls 0 ein gültiger Wert ist geht das nicht. Oft nimmt man negative Zahlen wenn diese nicht vorkommen können. Das ist aber eher der Fall wenn man z.B. Array Indizes zurückgibt, da diese nicht negativ sein können

Ansonsten gibt es noch die Option als Rückgabewert bool zu nehmen und für den Zahlenwert den man eigentlich möchte eine Referenz zu verwenden

Serenifly: void geht nicht. Er will ja was zurückgeben.

Wenn void nicht geht, weil etwas zurückgegeben werden muss, dann soll er das halt tun. Ich habe nur die Warnung gelesen, nicht den Code.

Serenifly: Ansonsten gibt es noch die Option als Rückgabewert bool zu nehmen ...

Bei bool würde keine Warnung ausgegeben werden?!

Gruß

Gregor

Ich halte es grundsätzlich nicht für einen guten Programmierstil, mitten aus einer Funktion mit return herauszuspringen. Ausnahmen können gegebenenfalls Fehlerbedingungen sein. Aber im Normalfall sollte die Funktion immer am Ende verlassen werden, und da steht dann auch das return mit dem zurückgegebenen Wert. Diesen Wert kann man dann innerhalb der Funktion in einer lokalen Variable setzen. Wird die noch mit einem ungültigen Fehlercode vorbelegt, ist auch der Fall abgedeckt, dass der Wert innerhalb der Funktion nicht gesetzt wird.

Danke euch allen.

Ich habe das 'return 0;' hinzugefügt, und nun ist die Warnung weg.

Frage: Wenn ich das '&' bei String hinzufüge, damit nicht eine Kopie des Objektes übergeben wird, besteht da nicht die gefahr, dass dann das Objekt selbst verändert wird? Ich weiss ja nicht, vielleicht wird das ja noch im unveränderten Zustand gebraucht.

Ist aber gut möglich, dass ich mich mit dieser Annahme völlig aufm Holzweg befinde.

Und ja, diese eine Warnung hat mich gestört, und darum hab ich hier nachgefragt, weil ich das weg haben wollte. Auch wenn deswegen vlt. nie was schief läuft, ich mochte es trotzdem nicht.

Also nochmals herzlichen Dank.

LG Stefan

Ja, mit &input wird das Original verändert. Je nachdem, was gemacht wird, ist dies nicht gewünscht.

Hier finde ich die Reaktion des Compilers etwas verwirrend:

int i = 5;

void ifkt(const int &in) {
  in = 33;
}
// liefert eine Fehlermeldung:

// error: assignment of read-only reference 'in'
//   in = 33;
//----------------------------------------------------
String s = "Hallo";

void fkt(const String &str) {
  str = " Welt";
}

// liefert lediglich eine Warnung:
// warning: passing 'const String' as 'this' argument discards qualifiers [-fpermissive]
//   str = " Welt";

Hat das einen Grund, den ich übersehe oder ist das ein Bug?

Gruß Tommy

Zuweisung an einen const Wert?

Ja, das ist ein Grund für einen Fehler.

Die Referenz ist immer const, das musst du nicht extra hinschreiben, wenn man es kann steht das const wohl woanders.

Das verstehe ich jetzt nicht. Es sind doch beides Mal Referenzen, die übergeben werden. Bei int verhindert das const die Änderung, bei String nicht.

Gruß Tommy

ElEspanol: Ja, mit &input wird das Original verändert. Je nachdem, was gemacht wird, ist dies nicht gewünscht.

Da der Code weder von mir noch für mich ist, und der Sketch bisher Problemlos gelaufen ist, (ich musste ihn lediglich erweitern) , belasse ich es beim hinzugefügten 'return 0;' und belasse es bei der Übergabe einer Kopie des Obijekts. Ich hab jetzt auch nicht die Zeit,es eingehender zu untersuchen, ob das Objekt im original weiter gebraucht wird oder nicht. Der Sketch möchte mMorgen mit meinen Erweiterungen in Betrieb genommen werden.

Ich bedanke mich herzlich für eure geschätze Hilfe.

LG Stefan

Tommy56: Das verstehe ich jetzt nicht. Es sind doch beides Mal Referenzen, die übergeben werden. Bei int verhindert das const die Änderung, bei String nicht.

Kommentierten Kode/Fehlermeldungen einfach ersetzen, pfui. Dann muss ich das nächste mal alles quoten, ich werde versuchen es mir zu merken.

Zu Strings kann ich dir nicht viel sagen, die verwende ich nur auf ESPs und da programmiere ich zu selten.

Da wurde nichts verändert, das siehst Du doch an den Zeitstempeln!

Also weißt Du es auch nicht, woher dieses unterschiedliche Verhalten kommt.

Gruß Tommy

Ich hatte den unteren Teil übersehen und aus "der Reaktion" fälschlich auf einen Fall gefolgert, sorry.

Nee, mit const Objekten habe ich noch nicht viel rumgespielt.

Als Ergänzung: Auf dem ESP8266 als Zielplattform wirft der Kompiler auch beim String einen ordentlichen Fehler:

String s = "Hallo";

void fkt(const String &str) {
  str = " Welt";
}

// ergibt:
// error: passing 'const String' as 'this' argument of 'String& String::operator=(const char*)' discards qualifiers [-fpermissive]

Das hängt evtl. mit der Implementation von String auf AVR zusammen. Für Structs wird auch auf AVR ein Fehler gemeldet.

Gruß Tommy