Warnings of deprecated conversion from string to char* while simulating a command line

A

Anton Pervukhin

Hello!

Imagine the situation you have a class that interprets the command line
of the program you are executing. This class is written by third party
and has a main function parse with arguments the same as main:

ClassA::parse(char **argv, int argc)

While trying to write test cases for this function I came across the
warnings appeared when I tried to initialize 'char** argv' straightly
from strings, like this:

argv[0] = "optionalProgramName";
argv[1] = "-a"; // some value argument
argv[2] = "aFileName.txt"; // its concrete value
argv[3] = "-nbc"; // some switch arguments
....

but that results in to warning: deprecated conversion from string
constant to `char*'. I'm using gcc 3.4.3 with strict warning policy: -W
-Wall -Wwrite-strings

Does somebody know the way to initialize char* with a constant string
that won't give warnings?

Several ways to do it for conversion to const char* is given in
Josuttis book for standart template library:
one could use std::string functions data(), or c_str() as following:

std::string s("1234");
const char* p;

p = s.c_str(); or
p = s.data();

but that is for const char* and doesn't work directly for char*. Should
one try to convert by putting const away, or there are easier ways to
do it?

The problem is not dramatic but it would be nice to have it without
warnings.

Any ideas will be appreciated.

Thanks.
 
V

Victor Bazarov

Anton said:
Imagine the situation you have a class that interprets the command line
of the program you are executing. This class is written by third party
and has a main function parse with arguments the same as main:

ClassA::parse(char **argv, int argc)

While trying to write test cases for this function I came across the
warnings appeared when I tried to initialize 'char** argv' straightly
from strings, like this:

argv[0] = "optionalProgramName";
argv[1] = "-a"; // some value argument
argv[2] = "aFileName.txt"; // its concrete value
argv[3] = "-nbc"; // some switch arguments
...

but that results in to warning: deprecated conversion from string
constant to `char*'. I'm using gcc 3.4.3 with strict warning policy: -W
-Wall -Wwrite-strings

Does somebody know the way to initialize char* with a constant string
that won't give warnings?

I'd probably go with

char argv0[] = "optionalProgramName";
char argv1[] = "-a";

....

argv[0] = argv0;
argv[1] = argv1;

....

OTOH, why don't you declare 'parse' to accept an array of pointers to
const char instead? You're not changing them, are you?

V
 
K

Karl Heinz Buchegger

Anton said:
argv[0] = "optionalProgramName";
argv[1] = "-a"; // some value argument
argv[2] = "aFileName.txt"; // its concrete value
argv[3] = "-nbc"; // some switch arguments
...

but that results in to warning: deprecated conversion from string
constant to `char*'. I'm using gcc 3.4.3 with strict warning policy: -W
-Wall -Wwrite-strings

Does somebody know the way to initialize char* with a constant string
that won't give warnings?

It seems that it is unclear to you on what the warning really refers to.

It talks about a constant string, such as

"optionalProgramName"

such a string has type
const char[]

note the const!

In the assignment the array decays to a pointer as usual, and you are
left with (just showing the data types)

char* = const char*

For this the compiler needs to drop the const on the right hand side of
the assignement. This is legal and was introduced in order to simplify
code migration from C to C++ but it is something you should be aware of
(hence the warning: the characters in such a string *are* constant and
you are not allowed to change them)

You have 2 options:
* either explicitely cast away the constness
* or do the things the right way and define the
argv varaible correctly as:

const char* argv[5];
argv[0] = "optionalProgramName";

Again: note the const!
 
R

Ron Natalie

Anton said:
Does somebody know the way to initialize char* with a constant string
that won't give warnings?
The problem is that string literals as you have used them really are
made up of const chars. You are violating const (but the language
grants a special exception for this) to initialize char* with them,
but you can't really modify the strings.

The easiest way around this would be just to allocate writable char
arrays:
char my_arg0[] = "whatever the first arg is";
and pass that to the array.
 
A

Anton Pervukhin

char argv0[] = "optionalProgramName";
char argv1[] = "-a";
....

argv[0] = argv0;
argv[1] = argv1;

Thanks! That works.
OTOH, why don't you declare 'parse' to accept an array of pointers to
const char instead? You're not changing them, are you?

No, I'm not changing them.
'parse' is taken from third party, therefore I cannot change it
directly.
I could advice to do it, but one thing prevents me:

if you have your main with lets say CommandLineParser object which has
'parse' function that just repeats the main arguments, like
following...

int main(int argc, char* argv[]) {

CommandLineParser parser;
parser.parse(argc, argv);
...
return ProgramInvoker.getInstance().run(parser.getArgument1(),
parser.getArgument2()...);
}

Can I have the declaration for 'parse' like this:

void CommandLineParser::parse(int argc, const char* argv[]); ?

I guess it won't work.
 
V

Victor Bazarov

Anton said:
[...]
OTOH, why don't you declare 'parse' to accept an array of pointers to
const char instead? You're not changing them, are you?


No, I'm not changing them.
'parse' is taken from third party, therefore I cannot change it
directly.

I was afraid you'd say that... :)
I could advice to do it, but one thing prevents me:

if you have your main with lets say CommandLineParser object which has
'parse' function that just repeats the main arguments, like
following...

int main(int argc, char* argv[]) {

CommandLineParser parser;
parser.parse(argc, argv);
...
return ProgramInvoker.getInstance().run(parser.getArgument1(),
parser.getArgument2()...);
}

Can I have the declaration for 'parse' like this:

void CommandLineParser::parse(int argc, const char* argv[]); ?

I guess it won't work.

No, it won't. Foo** is not convertible to const Foo**. You could try
declaring it as

void CommandLineParser::pars(int, const char* const* argv);

and that should be OK.

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,737
Latest member
Georgeengab

Latest Threads

Top