warning: ISO C++ forbids converting a string constant to 'char*'

Hi all,

I am quiet newbie at programming and don't know C++ or any other programming languages. although I am good at understanding what's in front of me and can use easily to my benefit.

so I have managed to whip up an Arduino program. I had it working few months ago and still is working in my Arduino by this day, although I have changed my Personal computer since last I programmed the Arduino and have the .ino file.

now I have installed Arduino IDE programmer again and I'm getting this warning message which wasn't there before.

I have no idea what is changed or what to do next.

the programme is below.

#include <OneWire.h>
#include <ST7735.h>
#include <SPI.h>
#include <DallasTemperature.h>

OneWire  ds(10);  // on pin 10
DallasTemperature sensor(&ds);

//const int potin = A0;
//int potValue = 0;
//int outputValue = 0;

int n = 1;
int Relay1 = 35;
int Relay2 = 37;
int Relay3 = 39;
int Relay4 = 41;
int Relay5 = 43;
int Relay6 = 45;
int Relay7 = 47;
int Relay8 = 49;

//Ultrasonic pin definition
#define trigger 12 //Ardino pin tied to trigger pin on ultrasonic sensor
#define echo    11  // Arduino pin tied to echo pin on the ultrasonic sensor.

//TFT pin definition
#define sclk 52
#define mosi 51
#define cs 53
#define dc 9
#define rst 8

//TFT colour difinition
#define	BLACK           0x0000
#define	RED             0x001F
#define	BLUE            0xF800
#define	GREEN           0x07E0
#define YELLOW          0x07FF
#define MAGENTA         0xF81F
#define CYAN            0xFFE0
#define WHITE           0xFFFF

ST7735 tft = ST7735(cs, dc, rst, mosi, sclk);
char temperature [20];
char SetP [8];

void setup() {
  pinMode(trigger, OUTPUT);
  pinMode(echo, INPUT);

  pinMode(A0, INPUT);

  pinMode(Relay1, OUTPUT);
  pinMode(Relay2, OUTPUT);
  pinMode(Relay3, OUTPUT);
  pinMode(Relay4, OUTPUT);
  pinMode(Relay5, OUTPUT);
  pinMode(Relay6, OUTPUT);
  pinMode(Relay7, OUTPUT);
  pinMode(Relay8, OUTPUT);

  digitalWrite(Relay1, LOW);
  digitalWrite(Relay2, LOW);
  digitalWrite(Relay3, LOW);
  digitalWrite(Relay4, LOW);
  digitalWrite(Relay5, LOW);
  digitalWrite(Relay6, LOW);
  digitalWrite(Relay7, LOW);
  digitalWrite(Relay8, LOW);

  sensor.begin();
  tft.initR(); // initialize a ST7735R chip
  //tft.writecommand(ST7735_DISPON);
  uint16_t time = millis();
  time = millis() - time;
  tft.fillScreen(WHITE);
  tft.drawString (0, 10, "---- System Data ---- ", RED);
  tft.drawString (0, 30, " Temperature: ", BLACK);
  tft.drawString (115, 30, "C" , BLACK);
  tft.drawString (0, 50, " SetPoint: ", BLACK);
  tft.drawString (0, 70, " Heater: ", BLACK);
  tft.drawString (0, 90, " Distance: ", BLACK);
  tft.drawString (115, 90, "Cm", BLACK);

}

void loop() {
  
  readtemp();
  float t = sensor.getTempCByIndex(0);
  int t1 = (t - (int)t) * 100;
  sprintf(temperature, "%0d.%d", (int)t, t1);

  float setpoint = 0.0;
  float volts = 0.0;
  int counts = 0;
  float ratio = 0.0;
  float baseTemperature = 10.0;
  float temperatureRange = 20.0;

  counts = analogRead (A0);
  ratio = (float)counts/1023.0;
  volts = 5.0*ratio;
  setpoint = (ratio*temperatureRange)+baseTemperature;
  dtostrf(setpoint, 6,2, SetP);

  if (t < setpoint) {
    digitalWrite(Relay1, HIGH);
    tft.drawString (50, 70, "ON", GREEN);
    delay(2);
    tft.drawString (80, 70, "OFF", WHITE);
  } else if (t > setpoint) {
    digitalWrite(Relay1, LOW);
    tft.drawString (80, 70, "OFF", RED);
    delay(2);
    tft.drawString (50, 70, "ON", WHITE);
  }

  tft.drawString (80, 30, temperature, BLACK);
  delay(5000);
  tft.drawString (80, 30, temperature, WHITE);
  delayMicroseconds(1);

  tft.drawString (60, 50, SetP, RED);
  delay (5000);
  tft.drawString (60, 50, SetP, WHITE);
  delay (1);

//  duration = (duration / 2);
//  distance = duration / 29.1;
//  tft.drawString (80, 70, distance, BLACK);
}

void readtemp(void) {
  sensor.requestTemperatures();
}

sorry I don't know how to embed the code in here.

Please post the full error message

(deleted)

C:\Users\Documents\Arduino\temp_sensor\temp_sensor.ino: In function 'void setup()':

C:\Users\Documents\Arduino\temp_sensor\temp_sensor.ino:78:55: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]

tft.drawString (0, 10, "---- System Data ---- ", RED);

^

C:\Users\Documents\Arduino\temp_sensor\temp_sensor.ino:79:49: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]

tft.drawString (0, 30, " Temperature: ", BLACK);

^

C:\Users\Documents\Arduino\temp_sensor\temp_sensor.ino:80:39: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]

tft.drawString (115, 30, "C" , BLACK);

it goes on for all tft.drawString lines.

It's a flaw in the definition of the library. The method should accept a 'const char *', but was implemented as 'char *' instead.

The design might be inherited from somewhere else (Adafruit GFX maybe?), so I don't know if it can be changed.

You can ignore the warning in this case.

In general, string constants ought to be treated as constants. It's bad design to write code that updates them. I mean … you totally can:

char *count = "Count X";

for(int i = 0; i<10;i++) {
  count[6] = '0' + i;
  println(count);
}

But it's bad design. Especially for things like microcontrollers, where string contsants might ge put in a special area of memory or otherwise handled in a weird way by the comiler.

The moment you assign a string to a char pointer and pass that char pointer to something else, that "something else" has no way to know (at compile time) that the pointer is in any way special. So, modern ANSI C compilers issue a warning, or even forbit it altogether depending on the compiler flags.

PaulMurrayCbr:
In general, string constants ought to be treated as constants. It's bad design to write code that updates them. I mean … you totally can:

char *count = "Count X";

for(int i = 0; i<10;i++) {
  count[6] = '0' + i;
  println(count);
}




But it's bad design. Especially for things like microcontrollers, where string contsants might ge put in a special area of memory or otherwise handled in a weird way by the comiler.

The moment you assign a string to a char pointer and pass that char pointer to something else, that "something else" has no way to know (at compile time) that the pointer is in any way special. So, modern ANSI C compilers issue a warning, or even forbit it altogether depending on the compiler flags.

so how would you go by designing it correctly?

You can safely ignore the warning messages for now, its only the last two or three versions of the IDE that have started issuing warning for this, I never noticed it prior to that. The cause, as stated in previous posts, is that a string literal is treated as a constant, but the function declaration has char *, not const char *, which tells the compiler that the function should be allowed to modify the contents of the memory that the char * points to. The warning is telling you that you have given something to the function that should not be altered, while at the same time you've given the function permission to alter it - the fact that the function doesn't actually modify the variable doesn't matter, its the fact that it has the ability to that generates the warning. The solution is to modify the function prototype and declaration in the library so that they expect to see a const.

babymomoh:
so how would you go by designing it correctly?

In PaulMurrayCbr's example, you can replace the first line with this:

char count[] = "Count X";

babymomoh:
so how would you go by designing it correctly?

In the declaration of the ST7735::drawString() function (in the library), change the third argument from 'char *' to 'const car *'. This is a promise to the compiler that ST7735::drawString() will not try to write into your string constant.