Partage
  • Partager sur Facebook
  • Partager sur Twitter

control reaches end of non-void function [-Werror=

    30 août 2021 à 12:30:11

    Salut ! j'ai cette erreur a la ligne 98 et je ne sais pas comment la résoudre, pouvez vous m'aider ?

    "control reaches end of non-void function [-Werror=return-type]"

    #define ARDUINOJSON_USE_DOUBLE 1
    #define ARDUINOJSON_USE_LONG_LONG 1
    
    #include <ESP8266WiFi.h>
    #include <ESP8266HTTPClient.h>
    #include <WifiClientSecure.h>
    #include <ArduinoJson.h>
    #include <Wire.h>
    #include "SH1106.h"
    #include "cryptos.h"
    
    // ----------------------------
    // Configurations - Update these
    // ----------------------------
    
    const char *ssid = "xxxxx";
    const char *password = "xxxxx";
    unsigned long screenChangeDelay = 10000;
    
    #define SCL_PIN D5
    #define SDA_PIN D3
    
    // ----------------------------
    // End of area you need to change
    // ----------------------------
    
    SH1106 display(0x3c, SDA_PIN, SCL_PIN);
    int cryptosCount = (sizeof(cryptos) / sizeof(cryptos[0]));
    HTTPClient http;
    WiFiClientSecure client;
    
    void renderSimpleText(String text)
    {
      display.clear();
      display.drawString(64, 18, text);
      display.display();
    }
    
    void renderWelcomeMsg()
    {
      display.setTextAlignment(TEXT_ALIGN_CENTER);
      display.setFont(ArialMT_Plain_16);
      display.drawString(64, 0, F("xxxxx"));
      display.setFont(ArialMT_Plain_10);
      display.drawString(64, 18, F("xxxxx"));
      display.drawString(64, 36, F("enjoy !"));
      display.display();
    }
    
    void connect()
    {
      WiFi.begin(ssid, password);
      String dots[3] = {".", "..", "..."};
      int numberOfDots = 1;
    
      while (WiFi.status() != WL_CONNECTED)
      {
        display.clear();
        display.setTextAlignment(TEXT_ALIGN_CENTER);
        display.setFont(ArialMT_Plain_10);
        display.drawString(64, 18, "Connecting to WiFi " + dots[numberOfDots]);
        display.display();
    
        if (numberOfDots == 3)
        {
          numberOfDots = 0;
        }
        else
        {
          numberOfDots++;
        }
    
        delay(300);
      }
    
      renderSimpleText("Connected.");
    }
    
    String createApiUrl(String vsCurrency)
    {
      String cryptosString = "";
    
      for (int i = 0; i < cryptosCount; i++)
      {
        cryptosString += cryptos[i].apiName + ",";
      }
    
      return "https://api.coingecko.com/api/v3/coins/markets?vs_currency=" + vsCurrency + "&ids=" + cryptosString + "&order=market_cap_desc&per_page=100&page=1&sparkline=false&price_change_percentage=24h%2C7d";
    }
    
    int getCryptoIndexById(String id)
    {
      for (int i = 0; i < cryptosCount; i++)
      {
        if (cryptos[i].apiName == id)
          return i;
      }
    }
    
    void downloadData(String vsCurrency)
    {
      http.useHTTP10(true);
      client.setInsecure();
    
      String apiUrl = createApiUrl(vsCurrency);
    
      client.connect(apiUrl, 443);
      http.begin(client, apiUrl);
    
      if (http.GET() != HTTP_CODE_OK)
      {
        renderSimpleText("Error connecting to API");
        return;
      }
    
      // Create a filter to reduce memory usage
    
      StaticJsonDocument<1024> filter;
    
      for (int i = 0; i < cryptosCount; i++)
      {
        filter[i]["id"] = true;
        filter[i]["symbol"] = true;
        filter[i]["current_price"] = true;
        filter[i]["price_change_percentage_24h_in_currency"] = true;
        filter[i]["price_change_percentage_7d_in_currency"] = true;
      }
    
      DynamicJsonDocument doc(8192);
      DeserializationError error = deserializeJson(doc, http.getStream(), DeserializationOption::Filter(filter));
    
      if (error)
      {
        Serial.print(F("deserializeJson() failed: "));
        Serial.println(error.f_str());
        renderSimpleText("JSON deserialization error");
        return;
      }
    
      for (int i = 0; i < cryptosCount; i++)
      {
        JsonObject json = doc[i];
        String id = json["id"];
        int cryptoIndex = getCryptoIndexById(id);
        String symbol = json["symbol"];
        symbol.toUpperCase();
        double currentPrice = json["current_price"];
        double dayChange = json["price_change_percentage_24h_in_currency"];
        double weekChange = json["price_change_percentage_7d_in_currency"];
    
        cryptos[cryptoIndex].symbol = symbol;
        cryptos[cryptoIndex].priceUsd = currentPrice;
        cryptos[cryptoIndex].dayChange = dayChange;
        cryptos[cryptoIndex].weekChange = weekChange;
      }
    }
    
    String formatCurrency(float price)
    {
      int digitsAfterDecimal = 3;
    
      if (price >= 1000)
      {
        digitsAfterDecimal = 0;
      }
      else if (price >= 100)
      {
        digitsAfterDecimal = 1;
      }
      else if (price >= 1)
      {
        digitsAfterDecimal = 2;
      }
      else if (price < 0.001)
      {
        digitsAfterDecimal = 4;
      }
    
      return String(price, digitsAfterDecimal);
    }
    
    void renderCryptoLogo(Crypto crypto)
    {
      int offX = 90;
      int offY = 4;
      int width = 32;
      int height = 32;
    
      display.drawXbm(offX, offY, width, height, (uint8_t *)(crypto.bitmap));
    }
    
    String formatPercentageChange(double change)
    {
      if (change >= 0)
      {
        return "+" + String(change) + "%";
      }
      else
      {
        return String(change) + "%";
      }
    }
    
    void renderCrypto(Crypto crypto)
    {
      display.clear();
      renderCryptoLogo(crypto);
      display.setTextAlignment(TEXT_ALIGN_LEFT);
    
      if (crypto.symbol.length() <= 3)
      {
        display.setFont(ArialMT_Plain_16);
        display.drawString(90, 45, crypto.symbol);
      }
      else
      {
        display.setFont(ArialMT_Plain_10);
        display.drawString(90, 50, crypto.symbol);
      }
    
      display.setFont(ArialMT_Plain_16);
      display.drawString(0, 10, "$");
      display.setFont(ArialMT_Plain_24);
      display.drawString(10, 6, formatCurrency(crypto.priceUsd));
      display.setFont(ArialMT_Plain_10);
      display.drawString(0, 42, "24h:  " + formatPercentageChange(crypto.dayChange));
      display.drawString(0, 54, "7d:  " + formatPercentageChange(crypto.weekChange));
      display.display();
    }
    
    void setup()
    {
      Serial.begin(115200);
      display.init();
      renderWelcomeMsg();
      delay(4000);
      connect();
    }
    
    void loop()
    {
      downloadData("usd");
    
      for (int i = 0; i < cryptosCount; i++)
      {
        renderCrypto(cryptos[i]);
        delay(screenChangeDelay);
      }
    }


    crypto.h

    struct Crypto
    {
      String apiName;
      char bitmap[128];
      String symbol;
      double priceUsd;
      double dayChange;
      double weekChange;
    };
    
    // ----------------------------
    // Add your cryptos to the array below
    //
    // First argument is a valid coin id from coingecko api (find id of your coin here https://api.coingecko.com/api/v3/coins/list?include_platform=false)
    // Second argument is a bitmap of a 32x32 image with cryptocurrency logo
    // ----------------------------
    
    Crypto cryptos[] = {
        {"bitcoin",
         {0x00, 0xf0, 0x0f, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x80, 0xff, 0xff, 0x01,
          0xc0, 0xff, 0xff, 0x03, 0xe0, 0xff, 0xff, 0x07, 0xf0, 0xff, 0xff, 0x0f,
          0xf8, 0xff, 0xfc, 0x1f, 0xfc, 0xff, 0xe4, 0x3f, 0xfc, 0x07, 0xe6, 0x3f,
          0xfe, 0x07, 0xf0, 0x7f, 0xfe, 0x1f, 0xc0, 0x7f, 0xfe, 0x1f, 0x82, 0x7f,
          0xff, 0x1f, 0x0f, 0xff, 0xff, 0x1f, 0x0f, 0xff, 0xff, 0x0f, 0x0f, 0xff,
          0xff, 0x0f, 0x80, 0xff, 0xff, 0x0f, 0xc0, 0xff, 0xff, 0x8f, 0x83, 0xff,
          0xff, 0x87, 0x87, 0xff, 0xff, 0xc1, 0x8f, 0xff, 0xfe, 0x81, 0x87, 0x7f,
          0xfe, 0x03, 0x80, 0x7f, 0xfe, 0x0f, 0xc0, 0x7f, 0xfc, 0x67, 0xf0, 0x3f,
          0xfc, 0x27, 0xff, 0x3f, 0xf8, 0x3f, 0xff, 0x1f, 0xf0, 0xff, 0xff, 0x0f,
          0xe0, 0xff, 0xff, 0x07, 0xc0, 0xff, 0xff, 0x03, 0x80, 0xff, 0xff, 0x01,
          0x00, 0xfe, 0x7f, 0x00, 0x00, 0xf0, 0x0f, 0x00}},
        {"ethereum",
         {0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00,
          0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xe0, 0x03, 0x00,
          0x00, 0xf0, 0x07, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xf8, 0x0f, 0x00,
          0x00, 0xfc, 0x1f, 0x00, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0xfe, 0x3f, 0x00,
          0x00, 0xff, 0x7f, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x80, 0xff, 0xff, 0x00,
          0x80, 0xff, 0xff, 0x00, 0xc0, 0xff, 0xff, 0x01, 0x00, 0xff, 0x7f, 0x00,
          0x40, 0xfc, 0x1f, 0x01, 0x80, 0xf9, 0xcf, 0x00, 0x00, 0xe7, 0x63, 0x00,
          0x00, 0x8e, 0x78, 0x00, 0x00, 0x3e, 0x3e, 0x00, 0x00, 0xfc, 0x1f, 0x00,
          0x00, 0xf8, 0x0f, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xf0, 0x07, 0x00,
          0x00, 0xe0, 0x03, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xc0, 0x01, 0x00,
          0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
        {"binancecoin",
         {0x00, 0x80, 0x01, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xe0, 0x07, 0x00,
          0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf8, 0x1f, 0x00, 0x00, 0xfc, 0x3f, 0x00,
          0x00, 0xfe, 0x7f, 0x00, 0x00, 0xff, 0xff, 0x00, 0x80, 0x7f, 0xfe, 0x01,
          0xc0, 0x3f, 0xfc, 0x03, 0x80, 0x1f, 0xf8, 0x01, 0x00, 0x0f, 0xf0, 0x00,
          0x00, 0x06, 0x60, 0x00, 0x1c, 0x80, 0x01, 0x38, 0x3e, 0xc0, 0x03, 0x7c,
          0x7f, 0xe0, 0x07, 0xfe, 0x7f, 0xe0, 0x07, 0xfe, 0x3e, 0xc0, 0x03, 0x7c,
          0x1c, 0x80, 0x01, 0x38, 0x00, 0x06, 0x60, 0x00, 0x00, 0x0f, 0xf0, 0x00,
          0x80, 0x1f, 0xf8, 0x01, 0xc0, 0x3f, 0xfc, 0x03, 0x80, 0x7f, 0xfe, 0x01,
          0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0xfc, 0x3f, 0x00,
          0x00, 0xf8, 0x1f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xe0, 0x07, 0x00,
          0x00, 0xc0, 0x03, 0x00, 0x00, 0x80, 0x01, 0x00}},
        {"",      
                                                       }};
                                                      



    -
    Edité par KyllianServières 30 août 2021 à 12:30:32

    • Partager sur Facebook
    • Partager sur Twitter
      30 août 2021 à 12:38:06

      Salut !

      Ajoute un return à la fin de la fonction incriminée. (quant à la valeur retournée, à toi de voir ce que tu veux retourner)

      Par contre, pense à utiliser les fonctions du header <algorithm> comme std::find_if dans le cas de cette même fonction.

      • Partager sur Facebook
      • Partager sur Twitter

      Si vous ne trouvez plus rien, cherchez autre chose.

        30 août 2021 à 13:57:21

        dragonjoker a écrit:

        Salut !

        Ajoute un return à la fin de la fonction incriminée. (quant à la valeur retournée, à toi de voir ce que tu veux retourner)

        Par contre, pense à utiliser les fonctions du header <algorithm> comme std::find_if dans le cas de cette même fonction.Il y a déjà un return i a la ligne 96

        Il y a déjà un return i a la ligne 96

        je dois ajouter un return0 après ? 

        -
        Edité par KyllianServières 30 août 2021 à 13:57:57

        • Partager sur Facebook
        • Partager sur Twitter
          30 août 2021 à 14:06:01

          Dans le cas ou cryptoCount est égal à 0.. que veux tu retourner ?
          • Partager sur Facebook
          • Partager sur Twitter
            30 août 2021 à 14:52:27

            ok j'ai rajouté un return 0 le programme compile

            mais c'est bizarre car j'avais déjà utilisé ce programme il y a quelque mois et il marchais très biens sans se return 

            update : le programme compile mais ne fonctionne plus (l'écran n'affiche plus rien)

            -
            Edité par KyllianServières 30 août 2021 à 14:53:13

            • Partager sur Facebook
            • Partager sur Twitter
              30 août 2021 à 16:06:55

              Salut,

              C'est le problème des renvois de valeur à l'intérieur des boucles...

              Quand tu as un code qui serait proche de

              Type maFonction(/* paramètres éventuels */){
                 for(/* ... */; /* ... */; /* ...*/){
                     if(une_condition)
                         return valeur;
                 }
              
              }

              le code va compiler et fonctionner, sans problème.

              Seulement, le compilateur va se rendre compte qu'il y a sans doute un cas auquel tu n'auras sans doute pas pensé: que se passe-t-il si la condition qui permet de renvoyer une valeur n'est jamais vérifiée?

              Ben la réponse est simple: on arrive à la fin de la fonction, et il n'y a pas de renvoi de valeur, alors que la fonction est sensée renvoyer quelque chose.

              Et donc, les concepteurs du compilateurs ont prévu le coup et on demandé au compilateur d'émettre un avertissement pour signaler le problème potentiel.

              Tu remarqueras au passage qu'il ne s'agit que d'un avertissement: c'est un message qui t'est fourni, mais tu peux (hormis si tu as ajouté une option qui demande de traiter les avertissements comme s'il s'agissait d'erreurs) parfaitement décider d'ignorer ce message.

              Après tout, tu peux estimer que les concepteurs du compilateur ont "simplement" réfléchi "un peu trop loin", car tu as la certitude que la condition sera respectée "à un moment ou à un autre".

              Oui, mais, heu... en est on vraiment aussi sur que cela??? Car la condition, dans le cas présent, est basée sur la valeur d'une donnée qui est transmise en paramètre.

              Or, cette valeur, ben, on ne sait pas d'où elle vient :p On ne sait pas, au niveau de la fonction, si la valeur transmise en paramètre est cohérente et correcte.  Et on ne sait même pas si des vérifications ont été faites ou non pour s'assurer que cette valeur  soit correcte et cohérente :'(

              Et donc, on ne peut absolument pas garantir que, quoi qu'il arrive, la condition sera forcément respectée à un moment ou à un autre à l'intérieur de la boucle.  Et, par conséquent, on ne peut pas garantir que nous n'arriverons jamais à la fin de la fonction sans qu'elle ne renvoie une valeur (re :'()

              Après, on peut ** peut-être ** s'intéresser au mécanisme qui permettrait d'arriver à la fin de la boucle sans que la condition ne soit vérifiée, et se dire que, si problème il y a, il provient d'office de l'appel de la fonction. 

              Si bien que l'on pourrait se dire que c'est le genre de problème qui devrait pouvoir être résolu "assez simplement" en rappelant à celui qui fera appel à  la fonction d'effectuer les vérifications "qui vont bien".

              Une simple assertion proche de

              Type maFonction(/* paramètres éventuels */){
                 for(/* ... */; /* ... */; /* ...*/){
                     if(une_condition)
                         return valeur;
                 }
                 assert(false && "Did you checked providen value?");
              }

              pourrait alors être "largement suffisant", tout en ignorant l'avertissement émis par le compilateur.

              Ou alors, on peut aussi se dire que celui qui appelle la fonction ne saurait pas faire la vérification avant d'appeler la fonction, vu que c'est -- justement -- la boucle qui permet de s'assurer que le paramètre reçu est "cohérent et correct".

              Et là, il va alors falloir s'interroger sur la réaction la plus "cohérente" à avoir face à ce problème.

              Car, si on arrive à la fin de la boucle, nous sommes, littéralement, dans une situation d'exception: une situation qui ne devrait (normalement) pas se présenter, mais dont on ne peut pas garantir qu'elle ne surviendra jamais, contre laquelle on ne peut strictement rien faire pour  éviter qu'elle ne se produise, et à laquelle nous n'avons absolument pas les moyens d'apporter une solution si elle vient à se produire.

              Dans l'idéal, il faudra donc arrêter séance tenante le traitement en cours, annuler tous les traitements qui ont pu être effectués avec les jeu  de données actuel (celui dont le paramètre fait partie), et remonter au moins jusqu'à l'endroit où la valeur servant pour le paramètre sera récupérée, car ce sera à peu près l'endroit du code où l'on aura la possibilité de résoudre le problème.

              Alors, ce qui est chouette, c'est que C++ est un langage à exceptions, et donc, que nous pourrions lancer systématiquement une exception (throw xxx; ) après la boucle, vu que, si on quitte la boucle, c'est que la condition que l'on pensait infaillible n'a jamais été remplie. Nous pourrions alors mettre un try ... catch "beaucoup plus haut" dans le code pour nous donner "une chance" de résoudre le problème s'il venait à se poser.

              Malheureusement, si notre code est destiné à travailler avec des bibliothèques C, les exceptions ne sont sans doute pas une option.

              Dans ce cas, il faudra prévoir de renvoyer une valeur connue pour représenter une valeur invalide et qui sera systématiquement vérifiée au niveau de la fonction appelante.

              • Partager sur Facebook
              • Partager sur Twitter
              Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait

              control reaches end of non-void function [-Werror=

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              • Editeur
              • Markdown