ISO C++ forbids

so this is my code

void render_history(char* secret, char** history, const int entry) {
  lcd_clear();
  lcd_print_at(0, 1, (char*)(entry + 1));
  lcd_print_at(2, 1, ":");
  lcd_print_at(4, 1, (history*[entry][0]));
  lcd_print_at(10, 1, history*[entry][1]);
  lcd_print_at(11, 1, "A");
  lcd_print_at(12, 1, history[entry][1]);
  lcd_print_at(13, 1, "B");
  render_leds(history[entry][1], history[entry][2]);
}

and this is my error

        ^
src\mastermind.cpp: In function 'void render_history(char*, char**, int)':
src\mastermind.cpp:132:25: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
   lcd_print_at(2, 1, ":");
                         ^
src\mastermind.cpp: In lambda function:
src\mastermind.cpp:133:38: error: expected '{' before '[' token
   lcd_print_at(4, 1, (history*[entry][0]));
                                      ^
src\mastermind.cpp: In function 'void render_history(char*, char**, int)':
src\mastermind.cpp:133:38: error: no match for 'operator[]' (operand types are 'render_history(char*, char**, int)::<lambda()>' and 'int')
src\mastermind.cpp: In lambda function:
src\mastermind.cpp:134:38: error: expected '{' before '[' token
   lcd_print_at(10, 1, history*[entry][1]);
                                      ^
src\mastermind.cpp: In function 'void render_history(char*, char**, int)':
src\mastermind.cpp:134:38: error: no match for 'operator[]' (operand types are 'render_history(char*, char**, int)::<lambda()>' and 'int')
src\mastermind.cpp:135:26: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
   lcd_print_at(11, 1, "A");
                          ^
src\mastermind.cpp:136:39: warning: invalid conversion from 'char' to 'char*' [-fpermissive]
   lcd_print_at(12, 1, history[entry][1]);
                                       ^
In file included from src\mastermind.cpp:2:0:
src\lcd_wrapper.h:50:6: note:   initializing argument 3 of 'void lcd_print_at(int, int, char*)'
 void lcd_print_at(int y, int x, char* text);
      ^
src\mastermind.cpp:137:26: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
   lcd_print_at(13, 1, "B");

Nnd this is my error. I am desperate i try almost everything. And i dont know what i am doing wrong. Can you help me with my code?

try ':' instead of ":"

i try but now i have another error
[argument of type "char" is incompatible with parameter of type "char *"]

Oops. Does this work ?

lcd_print_at(2, 1, (char *)":" ) ;

thanks one problem is solved but there is another
here is the error code
src\master.cpp:155:38: error: expected ‘{’ before ‘[’ token
lcd_print_at(10,1,history*[entry][1]);
^
src\master.cpp: In function ‘void render_history(char*, char**, int)’:
src\master.cpp:155:38: error: no match for ‘operator’ (operand types are ‘render_history(char*, char**, int)::<lambda()>’ and ‘int’)
src\master.cpp: In lambda function:
src\master.cpp:157:38: error: expected ‘{’ before ‘[’ token
lcd_print_at(12,1,history*[entry][1]);

Ideally, you'd post all your code and all the error messages. If the code is too big, then as an attachment. It appears that you are assuming that history is a pointer to a two dimensional array of pointers to a c_string.

Is there an online example you are following which you can link to ?

sorry but i cant show all my code because it is my school project.

I’m sorry I can’t show all my answer…because it is your school project.

The arguments to the lcd_print_at function (and possibly others as well) are incorrect. If you want to pass a string literal, you have to use an immutable pointer to a character string, aka const char *, not a mutable pointer char *.

Pieter

src\mastermind.cpp:132:25: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
   lcd_print_at(2, 1, ":");
                         ^

You can generally ignore this error warning. (thanks to the post below for pointing this out) The lcd_print_at() function expects a char* as the 3rd argument, but you are passing it a const char*, the compiler will handle this correctly regardless of the warning. To get rid of the warning, the lcd_print_at() function needs an overload to accept const char*.

The error messages related to history are a result of history being a char**, a pointer to a char pointer, and your treatment of it as an array. It may indeed be an array, we cannot tell from the code that you posted, and neither can the compiler at compile time. The code might be workable if it were a one-dimensional array, but to handle it as a two-dimensional array the compiler would need to know the size of at least the 2nd dimension so that it knows how large each of the elements for the 1st dimension are.

  lcd_print_at(0, 1, (char*)(entry + 1));

Can you explain what this is suppose to do? Subsequently you are using entry as an index to an array, but adding 1 and treating the result as a char* doesn't seem like it would produce any sensible output.

david_2018:

src\mastermind.cpp:132:25: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]

lcd_print_at(2, 1, ":");
                        ^



You can generally ignore this error.

warning != error

can anynone help me via private message?

nimand123:
can anynone help me via private message?

Usually not. It also deprives other readers access to the solution when it's found. Have you read and attempted any work with the three previous replies #8,9 and 10?

yes i something try but i realy dont understand what #8 means
#9 when i add char* the warning was fixed.
lcd print at is declared

void lcd_print(char* text){
    Serial.print(text);
    lcd.print(text);
}


void lcd_print_at(int y, int x,char* text){
    lcd_set_cursor(y, x);
    lcd_print(text);
}

nimand123:
#9 when i add char* the warning was fixed.

You are not allowed to do that (as indicated by "ISO C++ forbids"). By adding (char *), you're simply suppressing the warning by explicitly casting away the const qualifier, which is not good idea.

In general, casting away const like this invokes undefined behavior, and is wrong. In some cases, it might technically be legal, but even then, it is considered very bad practice.

The correct approach, which I alluded to in #8 is to fix the function signatures to use the right arguments:

void lcd_print(const char* text) {
    Serial.print(text);
    lcd.print(text);
}


void lcd_print_at(int y, int x, const char* text){
    lcd_set_cursor(y, x);
    lcd_print(text);
}

The type of string literals such as ":" is const char *, i.e. a read-only pointer to the first character of the string literal. The C++ standard (ISO C++) explicitly forbids writing to string literals, that's why the pointer is read-only (const).

If you cast away the const qualifier, you get a pointer to the string literal that is no longer read-only, which you could use to write. However, the pointer still points to the same string literal, and you're still not allowed to write to it! If you do try to write to it, your program breaks.

The correct way is to preserve the const qualifier throughout your program, as shown in the code above.

What I would do is define separate functions for char* and const char*, then the compiler will use the appropriate function depending on whether the argument in the function call is a string literal or a char array with variable data.

void lcd_print(char* text){
  Serial.print(text);
  lcd.print(text);
}

void lcd_print(const char* text) {
  Serial.print(text);
  lcd.print(text);
}

void lcd_print_at(int y, int x,char* text){
  lcd_set_cursor(y, x);
  lcd_print(text);
}

void lcd_print_at(int y, int x, const char* text){
  lcd_set_cursor(y, x);
  lcd_print(text);
}

In this case, the function doesn't alter the text, so you can be a bit more efficient by calling the const char* version from within the char* version, casting text to a const char*, but that might be considered bad programming form.

void lcd_print(char* text) {
  lcd_print((const char*) text);
}

void lcd_print(const char* text) {
  Serial.print(text);
  lcd.print(text);
}

void lcd_print_at(int y, int x, char* text) {
  lcd_print_at(y, x, (const char*) text);
}

void lcd_print_at(int y, int x, const char* text) {
  lcd_set_cursor(y, x);
  lcd_print(text);
}

david_2018:
What I would do is define separate functions for char* and const char*, then the compiler will use the appropriate function depending on whether the argument in the function call is a string literal or a char array with variable data.

Why would you do that? There's no reason why you couldn't pass a char * to a function that expects a const char *.
A normal pointer can be used as a read-only pointer without any special conversions.

Having a separate overload like you showed is completely unnecessary.

i add const char but i stiil have an error

argument of type "char" is incompatible with parameter of type "const char *"

nimand123:
i add const char but i stiil have an error

argument of type "char" is incompatible with parameter of type "const char *"

Did you use single or double quotes? You should use double quotes for strings, single quotes are for single characters.

I have problem in this line

lcd_print_at(4,1,history[entry][0]);
argument of type "char" is incompatible with parameter of type "const char *"