0

I want to get a filename from a commandline argument so I can pass it to a file-opening function, however, argv[] seems to be of type const char ** by default, even if it was defined as "const char * argv[]" in the main's arguments. My function requires const char *, is there a way to convert this two, or something?

int main(int argc, const char *argv[]) {
    memory Memory;
    Memory.loadROM(argv); // Error 'argument of type "const char **" is incompatible with parameter of type "const char *"'
}
Aureal
  • 77
  • 10
  • Note that `const char *var[]` or `const char **var` is rarely what you really mean. If you don't want to change the array elements, use `const char *const var[]` or `const char *const *var` instead. – aschepler May 18 '18 at 00:28
  • @aschepler Nope. `const char * const * const var` is right. Without the last `const`, you can do `var = some_other_thing`. – iBug May 18 '18 at 01:04

3 Answers3

5

When used in function parameters without being a reference type, const char *argv[] and const char **argv is exactly identical because the former will be adjusted to the latter.

Per N4296, Section 8.3.5p5:

any parameter of type “array of T” or “function returning T” is adjusted to be “pointer to T” or “pointer to function returning T,” respectively

So const char *argv[] is "an array of type const char *" and is thus adjusted to "a pointer to const char *".

And since argv is of type const char **, you want to dereference it to get a const char *:

Memory.loadROM(argv[1])
iBug
  • 35,554
  • 7
  • 89
  • 134
2

argv contains an array of char *, so if you only want one, simplify specify which you want:

Memory.loadROM(argv[1]);

Read here for more on what'll be in argv.

scohe001
  • 15,110
  • 2
  • 31
  • 51
-2

The difference between char* argv[] and char** argv is actually pretty subtle, so you'll often see them used interchangeably. The typical default is char** argv since that's more conventional, yet the alternative isn't wrong.

In both cases argv[0] is the first argument. Remember that pointers act like arrays and char* argv[] is an array of char*.

tadman
  • 208,517
  • 23
  • 234
  • 262
  • 1
    Subtle? I doubt they have any difference (when used as a function parameter). – iBug May 18 '18 at 00:35
  • One example of a subtle difference is in the case of `char** argv` you can do `argv++` and `argv = x`, but this is not allowed in the case of `char* argv[]`. These are not things you'd normally do, especially with `argv`, but it's one of those things that's *technically* true and C and C++ are all about technicalities. – tadman May 18 '18 at 00:38
  • 5
    @tadman: That is false. What you say is true if `argv` was actually an array. But a parameter named `char *argv[]` is exactly `char** argv`. It is in fact a pointer, not an array. Despite the misleading syntax. – Benjamin Lindley May 18 '18 at 00:40
  • @tadman While your claim looks really intuitive, it's actually *not* defined that way. See my answer above. – iBug May 18 '18 at 03:46