This question already has an answer here:
C++ warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
(1 answer)
Closed 8 years ago.
I want to use the execev function to run the texwork program from a fork of another program, and therefore, i have the following setup :
char *argVec[3];
argVec[0] = "texworks";
argVec[1] = "temp.tex";
argVec[2] = NULL;
execvp("texworks", argVec);
it works, but warns me :
Warnung: veraltete Konvertierung von Zeichenkettenkonstante in »char*« [-Wwrite-strings]
argVec[1] = "temp.tex";
that is : warning, old conversion from string constant to char* (the same warnign for argVec[0])
Should I be worried, and if so, how to i avoid this?
(oh, i am in Linux, 64 bit, g++ 4.8.1 -2013 prerelease, and const char* argVec[] = {"texworks" .. etc failes with this :
Fehler: ungültige Umwandlung von »const char**« in »char* const*« [-fpermissive]
execvp("texworks", argVec);
^
In file included from path/to/file:
/usr/include/unistd.h:578:12: Fehler: Argument 2 von »int execvp(const char*, char* const*)« wird initialisiert [-fpermissive]
extern int execvp (const char *__file, char *const __argv[])
^
/path/to/file:cursor:position: Fehler: Sprung zur case-Marke [-fpermissive]
default:
^
/path/to/file:cursor:position:: Fehler: überschneidet Initialisierung von »const char* argVec [3]«
const char * argVec[] = {"texworks" , "temp.tex", NULL};
The warning is legitimate, because assigning a "const char*" to a "char * " is dangerous. The data pointed to can be changed, but it shouldn't.
To build the argument vector using const char*, declare the array as a char const * const[]
To pass the array to execv, cast it to char**.
This version should avoid the warning:
char const * const argVec[] = {
"texworks"
, "temp.tex"
, NULL
};
execvp("texworks", (char**)argVec);
Related
I'm having issues with this two lines:
const unsigned char* sendstring = reinterpret_cast<const unsigned char *>( "Hello" );
txChar.writeValue(sendstring);
is giving me this error:
invalid conversion from 'const unsigned char*' to 'unsigned char' [-fpermissive]
I was trying to convert the sendstring variable in the first line but no.
I get the following error:
2 smartcard.c: In member function ‘virtual bool cSmartCards::ParseLine(const char*, bool)’:
3 smartcard.c:1187:25: error: invalid conversion from ‘const char*’ to ‘char*’ [-fpermissive]
4 char *r=index(line,':');
5 ^
The code is:
1184
1185 bool cSmartCards::ParseLine(const char *line, bool fromCache)
1186 {
1187 char *r=index(line,':');
1188 if(!r) return false;
I included "string.h"
How can I rewrite line 1187?
index() can be found in string.h.
Either or both of the following:
index returns const char*, not a char*. So, make r a const char*, not a char*.
The function index is written to expect a char*, not a const char*. I cannot safely suggest a fix for this without knowing what index is and does.
The answer is the following:
Function index is found in string.h.
Change line 1187 to: const char *r=index(line,':');
I have a huge list of errors that come up when i try to compile source code under cygwin.. My best approach to learning programming is hitting it hard, and trail and error. So even if my C++ knowledge is very basic, I am still really new, so please when you explain can I please ask that you use baby talk for a lack of a better word lol. When I type in 'make' under the source directory is gives me these errors. A friend of mine, we are friends on a MUD, he has been a programmer for 35 years and he says to me that the compiler is not liking that the function is returning a pointer and to change all the "return ''''" to return strdup('''')
Please let me know what you guys think. Thanks
Underneath is only a very smalllll part of the syntax that was given to me after I typed in make in Cygwin. I hope someone has the time to explain this to me, thank you.
$ make
make -s smaug
-Compiling o/imc.o....
imc.c:106:1: error: deprecated conversion from string constant to ‘char*’ [-Werror=write-strings]
};
^
imc.c:106:1: error: deprecated conversion from string constant to ‘char*’ [-Werror=write-strings]
imc.c:106:1: error: deprecated conversion from string constant to ‘char*’ [-Werror=write-strings]
imc.c:106:1: error: deprecated conversion from string constant to ‘char*’ [-Werror=write--strings]
imc.c:106:1: error: deprecated conversion from string constant to ‘char*’ [-Werror=write-strings]
imc.c:106:1: error: deprecated conversion from string constant to ‘char*’ [-Werror=write-strings]
imc.c: In function ‘char* color_itom(const char*, CHAR_DATA*)’:
imc.c:393:14: error: deprecated conversion from string constant to ‘char*’ [-Werror=write-strings]
return "";
^
imc.c: In function ‘char* color_mtoi(const char*)’:
imc.c:414:14: error: deprecated conversion from string constant to ‘char*’ [-Werror=write-strings]
return "";
^
imc.c: In function ‘char* imccapitalize(const char*)’:
imc.c:525:35: error: conversion to ‘char’ from ‘int’ may alter its value [-Werror=conversion]
strcap[i] = tolower( str[i] );
^
imc.c:527:35: error: conversion to ‘char’ from ‘int’ may alter its value [-Werror=conversion]
strcap[0] = toupper( strcap[0] );
^
imc.c: In function ‘void imc_new_channel(const char*, const char*, const char*, const char*, const char*, bool, int, const char*)’:
imc.c:1089:13: error: conversion to ‘short int’ from ‘int’ may alter its value [-Werror=conversion]
c->level = perm;
^
^
cc1plus: all warnings being treated as errors
Makefile:101: recipe for target 'o/imc.o' failed
make[1]: *** [o/imc.o] Error 1
Makefile:46: recipe for target 'all' failed
make: *** [all] Error 2
Ok below is the code where it shows error for line 106: 1 and 393: Its a very lonnng .c file I am sure you guys don't want to upload the whole thing, but here is the portion of it, and according to Visual 2013 here is starting point line 106 and 393: i am not sure when cygwin says the line number where the error took place if that doesn't include white space and comments, but here is 106 and 393 according to VS:
line 106
SITEINFO *this_imcmud;
line 393
if( IMCIS_SET( IMCFLAG( ch ), IMC_COLORFLAG ) )
You should show your code, but your problems are:
Somewhere you're doing something like:
char *x = "hello";
It should be:
const char *x = "hello";
Similarly, char* color_itom(const char*, CHAR_DATA*) should return const char * if you want to return string literals from it.
strcap is defined as a char array, but you're putting the int values returned by tolower and toupper in there somewhere. Either change the type or put in an explicit cast.
Same for c->level = perm. Either add an explicit cast or change the type of c->level to match the type of perm.
The error:
deprecated conversion from string constant to ‘char*’
is caused by using string literal to initiaize char*, e.g.
char* str = "something";
This should read:
const char* str = "something";
While adding a detailed answer, I noticed that GCC does not warn the following code while Visual C++ complains.
#include <cstring>
int main()
{
const char CONSTSTR[] = "foo/bar/foobar.txt";
char *nonconst = std::strrchr (CONSTSTR, '/');
// cannot convert from 'const char *' to 'char *'
*nonconst++ = 'B';
*nonconst++ = 'A';
*nonconst++ = 'D';
}
I have tested three different GCC versions:
4.1.2 on Red Hat (Linux)
4.5.3 on Cygwin (Windows)
4.7.2 on MinGW (Windows)
But all these three GCC versions compiled this code without any warning/error:
> g++ -Wall -Wextra -pedantic -ansi test.cpp && echo "success"
success
While Microsoft compiler v16 complains:
> cl -c test.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
test.cpp
test.cpp(5) : error C2440: 'initializing' : cannot convert from 'const char *' to 'char *'
Conversion loses qualifiers
(from my office, I do not have access to ideone/codepad/... to test it using other versions)
As this code uses std::strrchr, I do not understand why GCC does not complain.
const char* strrchr( const char* str, int ch ); //the code above uses this declaration
char* strrchr( char* str, int ch );
My question: Why does g++ successfully compile this code without any warning/error? Is it a bug? a feature? a miss-configuration on my side?
Actually your g++ does not accept the conversion from 'const char *' to 'char *', it's just that on your version std::strrchr() returns a char* (incorrectly, instead of a const char*).
To verify the first part of my statement, try to compile the following on your GCC versions, I predict that all will correctly issue an error:
int main()
{
const char* p = "foo";
char* q = p; // error, invalid conversion from 'const char*' to 'char*'
}
Now for the second part, I tried to compile the following minimal code, whose actual aim is to trigger an error in order to list the declared overloads of std::strrchr:
#include <cstring>
void (*p)() = &std::strrchr; // error here, with "candidates are: ..."
int main() {}
Well, with gcc 4.7.2 the message shows the expected "all non-const" and "all const" overloads:
prog.cpp:2:21: error: no matches converting function ‘strrchr’ to type ‘void (*)()’
In file included from /usr/include/c++/4.7/cstring:44:0,
from prog.cpp:1:
/usr/include/string.h:249:1: error: candidates are: char* strrchr(char*, int)
/usr/include/string.h:255:1: error: const char* strrchr(const char*, int)
i.e. the prototypes
char* strrchr( char* , int );
const char* strrchr( const char* , int ); // Question's code will use this one (-> error)
But with gcc 4.3.2 the message was different:
prog.cpp:2: error: no matches converting function 'strrchr' to type 'void (*)()'
/usr/include/string.h:171: error: candidates are: char* strrchr(const char*, int)
/usr/include/c++/4.3/cstring:118: error: char* std::strrchr(char*, int)
i.e. the overloads were
char* strrchr( const char* , int ); // Question's code would use this one (-> no error...)
char* strrchr( char* , int );
(the second one is the C++ non-const overload; but the first one is the old C version, and should instead be the C++ const overload).
This it seems that the headers (<cstring> and/or <string.h>) were incorrect on this version, and I suspect that it's the same on yours.
Edit: I found for example a discussion, a blog post and a bug report (for strchr not strrchr but it's the same story).
I am trying to compile some code that was given to me that I'm told compiles fine. Perhaps on a different compiler. I am using VS2010 and I have the following line:
char *dot = strrchr(filename, '.');
This causes the compiler error:
"error C2440: 'initializing': cannot convert from 'const char *' to
'char *'
How come? And how do I fix it?
The error message is pretty clear. strrchr returns a const char*. So you need:
const char *dot = strrchr(filename, '.');
If you really need a char*, you can use strcpy for conversion.
C++ has saner versions of strchr and strrchr than C thanks to overloading, so say:
const char * dot = strrchr(filename, '.');
In C, which has no overloading, you only have a single function char * strrchar(const char *, const char *), and it's up to you to decide whether the result is constant or mutable, depending on which type of pointer to feed into the function. C has many such type-unsafe functions.