c++ How could I properly predefined array of char*?
-
10-10-2019 - |
Question
I am doing it that way:
int argc = 9;
char* argv[argc];
argv[0] = "c:/prog.exe";
but I get notice, that it is deprecated. What is better way?
Solution
You have to either make it const:
const char *argv[] = { "Arg1", "Arg2", "..." };
... or not use the constant string literals:
int argc = 9;
char* argv[argc];
char prog_name[] = "c:/prog.exe";
argv[0] = prog_name;
OTHER TIPS
Besides the problem of using something other than a constant expression for your array size...
The thing that has been deprecated is the silent casting of string literals to char*
. This used to be OK:
char * hello = "hello";
Now it has to be:
char const* hello = "hello";
This deprecation is actually in an Appendix in C++03.
Let analyze what you are doing here:
// Create an int with value 9.
int argc = 9;
// Create an array of char* pointers of size 9
char* argv[argc];
// Assign the the first pointer to the global data string "C:\prog.exe"
argv[0] = "c:/prog.exe";
My guess is that you are not trying to do what I've described above. Try something like this:
// create an array of characters
char argv[] = "C:/prog.exe";
// argc in now the length of the string
int argc = sizeof argv;
-or -
// create an array of strings
char* argv[] = {"C:/prog.exe"};
// argc is now the number of strings in the array
int argc = 1;
Try using const
to indicate that the strings won't be modified.
const char* argv[] = { "c:/prog.exe" };
const int argc = sizeof(argv) / sizeof(argv[0]);
int main()
{
for(int i = 0; i < argc; ++i)
{
::printf("%s\n", argv[i]);
}
}
Here, argc
will also be calculated at compile time automatically so there's a lesser chance of error (thanks to Goz for the suggestion).
+1 for Vlad.
Some more explanation from me on what happens here:
You get the "deprecated" warning, because such code:
"asdf"
now has type const char*
, not char*
. And string literals can be converted to char*
, to retain some compatibility with the older conventions when const
wasn't that strict. But conversion of a string literal to char*
from const char*
is deprecated and you should not rely on it.
Why? String literal is a pointer to constant memory, that's why it needs to be const char*
.
Other than what everyone else has pointed out about const string literals being assigned to non-const char pointers and the weirdness of declaring argv and argc outside of main()'s parameter list, there is an additional problem with this line here:
char* argv[argc];
You can only use integer constant expressions for array sizes in C++; an integer constant expression being a literal integer in the source of your program (like "5" or "10"), an enumerations value (like "red" from "enum colors {red, green, blue};"), a sizeof expression, or an int variable declared with const:
// can hold 30 ints
int myarray1[30];
// can hold as many ints as myarray1 is wide in bytes
int myarray2[sizeof(myarray1)];
// C++ does not support variable-length arrays like C99 does, so if an int
// variable is used to specify array size, it must be marked const:
const int myarray3_size = 42;
int myarray3[myarray3];
Many C++ compilers implement C99-style variable-length arrays, so you may not get any complaint when you use them, but they are still best avoided if you want to write portable code.