How do I declare a pointer to a pointer to a constant in C ++?
I am trying to write a function to parse command line arguments. This is the function declaration:
void parse(int, char const **);
Just in case, I've also tried it (const char)**
, const char **
and cchar **
with help typedef const char cchar
. However, all of them (as expected, since they should all be the same) result in an error if I pass a char **
to a function, as in:
void main(int argc, char **argv) {
parse(argc, argv);
The error I get from the GNU compiler is error: invalid conversion from 'char**' to 'const char**'
, and one from Clang is candidate function not viable: no known conversion from 'char **' to 'const char **' for 2nd argument
.
I've seen solutions like this that suggested declaring a pointer to pointer const to char ( const char * const *
), but I don't want any pointer to be const, because I want to be able to modify the pointer so that I can iterate over the argument using for(; **argv; ++*argv)
. How can I declare "non-const pointer to non-const pointer to const char"?
source to share
The safest signature that prevents modification of arguments by allowing any other combination to const
call the function:
parse(int argc, char const* const* argv);
This means it argv
is a pointer to a pointer const
toconst char
You can happily iterate over parameters like this:
for(auto arg = argv + 1; *arg; ++arg)
{
if(!std::strcmp(*arg, "--help"))
return print_help();
else if(!std::strcmp(*arg, "-v") || !std::strcmp(*arg, "--verbose"))
verbose_flag = true;
// ... etc...
}
Note, there is no need to accept a variable int argc
because the array of character arrays is null terminated.
So I usually use this:
struct config
{
// program options and switches
};
config parse_commandline(char const* const* argv);
source to share
The function must be declared as:
void parse(int, char const * const *);
In C ++ it char **
can implicitly add const
at all pointer depths, so you can call it like parse(argc, argv)
.
In C, const
can only be added at the first pointer depth (this is a design defect in the language). Here is the dedicated stream . So you have to call the function like: parse(argc, (char const * const *)argv);
unfortunately.
source to share