Home > Blockchain >  error: ISO C forbids converting a string constant to ‘char*’
error: ISO C forbids converting a string constant to ‘char*’

Time:04-25

I'm trying to run the following code, taken from "Object Oriented Programming with C " by Balagurusamy (8th edition):

#include <iostream>
#include <cstring>
using namespace std;

class String
{
char *name;
int length;

public:

String()
{
length = 0;
name = new char[length 1];
}

String(char *s)
{
length = strlen(s);
name = new char[length 1];
strcpy(name,s);
}

void display(void)
{cout<<name<<"\n";}
void join(String &a, String &b);

};

void String :: join(String &a, String &b)
{
length = a.length   b.length;
delete name;
name = new char[length 1];

strcpy(name, a.name);
strcat(name, b.name);
};


int main()
{

char *first = "Joseph ";

String name1(first), name2("Louis"), name3("Lagrange"), s1,s2;

s1.join(name1, name2);
s2.join(s1,name3);

name1.display();
name2.display();
name3.display();

s1.display();
s2.display();

return 0;
}

When I compile with g , I run into the following log:

g   -Wall -Werror -Wextra constructors_with_new.cpp -o constructors_with_new.o
constructors_with_new.cpp: In function ‘int main()’:
constructors_with_new.cpp:45:15: error: ISO C   forbids converting a string constant to ‘char*’ [-Werror=write-strings]
   45 | char *first = "Joseph ";
      |               ^~~~~~~~~
constructors_with_new.cpp:47:28: error: ISO C   forbids converting a string constant to ‘char*’ [-Werror=write-strings]
   47 | String name1(first), name2("Louis"), name3("Lagrange"), s1,s2;
      |                            ^~~~~~~
constructors_with_new.cpp:47:44: error: ISO C   forbids converting a string constant to ‘char*’ [-Werror=write-strings]
   47 | String name1(first), name2("Louis"), name3("Lagrange"), s1,s2;
      |                                            ^~~~~~~~~~
cc1plus: all warnings being treated as errors


Then I found the following answer

Why is conversion from string constant to 'char*' valid in C but invalid in C

and to make it work, I modified the above code

  1. to receive a pointer to const char inside the 2nd constructor (String(char const *s))
  2. inside main(), by changing the initialization of the first name "Joseph", from char * first to char const * first, as suggested by Jeremy Coffin in the answer to the provided link

In this way, it compiles without problems with the following output

Joseph 
Louis 
Lagrange
Joseph Louis 
Joseph Louis Lagrange

What I wonder is whether this is the best way to fix this problem, or if you recommend a different way (maybe another that doesn't need to enter a pointer to a const of type char).

Best,

Stefano

CodePudding user response:

As the comments indicate, you need to use const char*, not char*. It looks like the book is badly out of date.

In C , a string literal is of type const char[N], where N is the number of characters in the literal plus one for the terminating '\0'.

I was able to make your code compile and run by making the following changed:

  • Change the constructor for String from
    String(char *s)
    to
    String(const char *s)
  • Change the declaration of first from
    char *first = "Joseph ";
    to
    const char *first = "Joseph ";
  • Remove the extraneous semicolon at the end of String::join.

Also, the code would be a lot more legible with proper indentation.

CodePudding user response:

A string literal in C is by default a const char*. That's why you are seeing these warnings where you are trying to assigning a const char* to a char*.

You can simply remove these warnings by casting away the constness of the char*. You can achieve this by using const_cast<char*>

Eg:

char *first = const_cast<char*>("Joseph ");

String name1(first), name2(const_cast<char*>("Louis")), name3(const_cast<char*>("Lagrange")), s1,s2;

This should remove your warning.

Edit: This is not the best advice. My answer is only meant to explain how you can cast away const-ness of the string literal and in no way promotes it. The constness of string literal exists for a reason.

  • Related