Go Down

Topic: How to avoid triggering this complier warning (Read 142 times) previous topic - next topic

ShermanP

The sketch compiles, and runs properly, but I would like to write the code correctly so the warnings don't occur.  Here is the relevant code section, and the compiler warnings:

Code: [Select]

#include <ESP8266WiFi.h>

#define ssid "yourSSID"
#define password "yourpassword"

#define webhookskey "yourwebhookskey"
#define eventname1 "MailboxOpened"
#define eventname2 "DoorLeftOpen"

const int httpsPort = 443;
const int powerPin = D2;
char* trigger1 = "/trigger/" eventname1 "/with/key/" webhookskey;
char* trigger2 = "/trigger/" eventname2 "/with/key/" webhookskey;
char* event = trigger1;
.
.
.


C:\arduino-1.8.8\Portable\sketchbook\MailboxNotifier\MailboxNotifier.ino:13:21: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

 #define webhookskey "yourwebhookskey"

                     ^

C:\arduino-1.8.8\Portable\sketchbook\MailboxNotifier\MailboxNotifier.ino:20:54: note: in expansion of macro 'webhookskey'

 char* trigger1 = "/trigger/" eventname1 "/with/key/" webhookskey;

                                                      ^

C:\arduino-1.8.8\Portable\sketchbook\MailboxNotifier\MailboxNotifier.ino:13:21: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

 #define webhookskey "yourwebhookskey"

                     ^

C:\arduino-1.8.8\Portable\sketchbook\MailboxNotifier\MailboxNotifier.ino:21:54: note: in expansion of macro 'webhookskey'

 char* trigger2 = "/trigger/" eventname2 "/with/key/" webhookskey;

                                                      ^



I would like to know why it is wrong and how it should be done.  Also, why does the compiler object to webhookskey, but not to eventname1 or eventname2 which are used in exactly the same way?

pylon

I just compiled that sketch:

Code: [Select]
#define webhookskey "yourwebhookskey"
#define eventname1 "MailboxOpened"
#define eventname2 "DoorLeftOpen"

const int httpsPort = 443;
const int powerPin = 2;
char* trigger1 = "/trigger/" eventname1 "/with/key/" webhookskey;
char* trigger2 = "/trigger/" eventname2 "/with/key/" webhookskey;
char* event = trigger1;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println(trigger1);
  Serial.println(trigger2);
}

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

}


on a 1.8.10 IDE without any warning. Please provide a minimal complete code that produces your warning message!

arduino_new

Those variables need to be marked as const;

ShermanP

pylon, I'm running IDE v1.8.8 and ESP8266 core v2.5.2, and the board is Lolin d1 mini.  As I said, it does compile successfully, but with warnings ahead of the memory and ram usage summary.  I don't know what you want me to post, so here's the whole thing:

Code: [Select]

/*
This is a mailbox notifier sketch for a Lolin D1 Mini.  It was compiled
using the Arduino IDE v1.8.8 with ESP8266 Core v2.5.2. Two IFTTT events
are used, the first notifying that the mailbox has been opened, and the
second notifying that the mailbox door has been left open.
*/

#include <ESP8266WiFi.h>

#define ssid "yourSSID"                          //SSID and PW of your router
#define password "yourpassword"

#define webhookskey "yourwebhookskey"            //enter your Webhooks key here
#define eventname1 "MailboxOpened"               //IFTTT event - mailbox opened
#define eventname2 "DoorLeftOpen"                //IFTTT event - door left open

const int API_TIMEOUT = 15000;
const int httpsPort = 443;
const int powerPin = D2;                         //power kept on by this pin
char* trigger1 = "/trigger/" eventname1 "/with/key/" webhookskey;
char* trigger2 = "/trigger/" eventname2 "/with/key/" webhookskey;
char* event = trigger1;
const char* server = "maker.ifttt.com";
bool result = true;

void setup() {
  pinMode(powerPin, OUTPUT);                     //keep power on
  digitalWrite(powerPin, HIGH);

  delay(5000);
  Serial.begin(57600);                           //ignored if no connection
  delay(100);

  if(connectToWifi()) {                          //if connect ok, send GET
    makeIFTTTRequest();
  }
  WiFi.disconnect();

  Serial.println("Turning off power");
  delay(1000);
  digitalWrite(powerPin, LOW);                   //if door closed, this will
                                                 //   turn off power

  delay(60000);                                  //this completes if power still on
  Serial.println();
  Serial.println();
  Serial.println("Door left open, power still ON, sending notification");
  event = trigger2;                              //send door open notice
  if(connectToWifi()) {
    makeIFTTTRequest();
  }
  WiFi.disconnect();
  Serial.println("Going to sleep now");
  ESP.deepSleep(0);                              //power will turn off when
}                                                //   door eventually closed

void loop(){
}

// Establish WiFi connection to the router

bool connectToWifi() {
  WiFi.disconnect();
  Serial.print("Connecting to: ");
  Serial.println(ssid);
  WiFi.mode(WIFI_STA);                           //connect as client
  WiFi.begin(ssid, password);                    //connect to router
  Serial.print("Attempting to connect: ");

  int i = 16;                                    //try to connect for 15 seconds
  while((WiFi.status() != WL_CONNECTED) && (i-- > 0)) {
    delay(1000);
    Serial.print(i);
    Serial.print(", ");
  }
  Serial.println();

  //print connection result
  if(WiFi.status() == WL_CONNECTED){
    Serial.println("Connected.");
    Serial.print("D1 Mini IP address: ");
    Serial.println(WiFi.localIP());
    result = true;
  }
  else {
    Serial.println("Connection failed - check your credentials or connection");
    result = false;
  }
  return result;
}

// Make an HTTP request to the IFTTT web service

void makeIFTTTRequest() {
  Serial.print("Connecting to ");
  Serial.print(server);

  BearSSL::WiFiClientSecure client;

  for (int tries = 0; tries < 5; tries++) {        //try up to 5 times to connect
    client.setTimeout(API_TIMEOUT);
    client.setInsecure();                          //don't check fingerprint
    if(client.connect(server, httpsPort)) break;   //exit FOR loop if connection
    Serial.print(".");                             //  else wait, try again
    delay(2000);
  }

  Serial.println();
  if(!client.connected()) {
    Serial.println("Failed to connect to server");
    client.stop();
    return;                                      //if no connection, bail out
  }
  Serial.print("Request event: ");               //if good connection, send GET
  Serial.println(event);
  client.print(String("GET ") + event +
                  " HTTP/1.1\r\n" +
                  "Host: " + server + "\r\n" +
                  "Connection: close\r\n\r\n");

  int timeout = 50;                              //wait 5 seconds for a response
  while(!client.available() && (timeout-- > 0)){
    delay(100);
  }

  if(!client.available()) {
     Serial.println("No response to GET");
     client.stop();
     return;
  }
  while(client.available()){
    Serial.write(client.read());
  }
  Serial.println("\nclosing connection");
  delay(1000);
  client.stop();
}



wildbill

If you're not seeing warnings, crank up compilation warning settings in preferences to all.

ShermanP

Those variables need to be marked as const;
Which variables?  If I change the definitions of trigger1 and trigger2 to const char*, the compile fails, with this error message:

Code: [Select]

MailboxNotifier:22:15: error: invalid conversion from 'const char*' to 'char*' [-fpermissive]

 char* event = trigger1;

               ^



arduino_new

Code: [Select]

const char* trigger1 = "/trigger/" eventname1 "/with/key/" webhookskey;
const char* trigger2 = "/trigger/" eventname2 "/with/key/" webhookskey;
const char* event = trigger1;


The reason for this is because on most platforms, literal strings are placed in READONLY section.

ShermanP

Code: [Select]

const char* trigger1 = "/trigger/" eventname1 "/with/key/" webhookskey;
const char* trigger2 = "/trigger/" eventname2 "/with/key/" webhookskey;
const char* event = trigger1;


The reason for this is because on most platforms, literal strings are placed in READONLY section.
The variable *event* can't be a const because later in the code its value will be changed to equal trigger2.


arduino_new

The variable *event* can't be a const because later in the code its value will be changed to equal trigger2.


Code: [Select]

const char* trigger1 = "/trigger/" eventname1 "/with/key/" webhookskey;
const char* trigger2 = "/trigger/" eventname2 "/with/key/" webhookskey;
char const *event = trigger1 ;

ShermanP

Code: [Select]

const char* trigger1 = "/trigger/" eventname1 "/with/key/" webhookskey;
const char* trigger2 = "/trigger/" eventname2 "/with/key/" webhookskey;
char const *event = trigger1 ;

Ok.  That compiles with no warnings, and runs correctly.

But I still don't understand what was wrong with my original code, which had none of these variables as const.  Might have used more ram, but it seems it ought to work.  Well, I guess it would have compiled with no warnings in C, and it does in fact run fine, but just isn't quite right in C++.  I don't understand why.

Anyway, thanks for your help.

gfvalvo

#10
Nov 19, 2019, 11:25 pm Last Edit: Nov 19, 2019, 11:26 pm by gfvalvo
This allows you to change the value of the constant literal via the pointer (bad):
Code: [Select]
char *var = "Hello World";

This does not:
Code: [Select]
const char *var = "Hello World";

But, you can still change the pointer which would strand your literal in memory (also bad). So use this:
Code: [Select]
const char * const var = "Hello World";

or this:
Code: [Select]
const char var[] = "Hello World";
No technical questions via PM. They will be ignored. Post your questions in the forum so that all may learn.

Go Up