0

When you want to handle command-line arguments, you can define the main function like the below.

int main(int argc, char **argv) { ... }

or

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

In many websites, it is explained that the first argv is a pointer to a pointer, and the second one is an array of pointers. But, is this true? Actually, even when you use the second definition, you can set argv as the LHS of = operator, which I think isn't allowed if argv is truly an array. In my opinion, "when written as a function's parameter", char **argv and char *argv[] are completely equal. However, I haven't found the evidence.

Could anyone help me? (What I would like to have is strictly or officially written evidence.)


Note: I've already read the threads below. I believe my post isn't a duplicate of them.

What Is The Difference Between char**x and char*x[]

In C, are arrays pointers or used as pointers?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
ynn
  • 3,386
  • 2
  • 19
  • 42

4 Answers4

6

Well, there's always the C standard:

5.1.2.2.1 Program startup

1 The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters: int main(void) { /* ... / } or with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared): int main(int argc, char *argv[]) { / ... */ } or equivalent;9) or in some other implementation-defined manner.

9) Thus, int can be replaced by a typedef name defined as int, or the type of argv can be written as char ** argv, and so on.

Which says -- according to footnote (9) -- char *argv[] is equivalent to char **argv.

Mark Benningfield
  • 2,800
  • 9
  • 31
  • 31
1

In many websites, it is explained that the first argv is a pointer to a pointer, and the second one is an array of pointers. But, is this true?

This is not true when an array is declared as a parameter of a function. argv in both signature of main is of type char ** (pointer to pointer to char).
In C, an array can't be passed to a function, but pointer to it. When you declare a parameter of a function as an array type then compiler treat it as a pointer type. Below prototypes are equivalent

int foo1(int a[10], int size);
int foo2(int a[], int size);
int foo3(int *a, int size);

Same apply with char *argv[], as a function parameter it is equivalent to char **argv

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
haccks
  • 104,019
  • 25
  • 176
  • 264
  • So my opinion is right? But, do you have a written evidence? I think what you are saying is so natural, though. – ynn Mar 04 '18 at 18:09
  • @ynn Just search for the appropriate topic [at this website](https://port70.net/~nsz/c/c11/n1570.html), and you would conclude that arrays in [tag:c] are very special and you can't really pass an array as a parameter. The main reason is that you can only pass a pointer to it's first element when it's the parameter of a function. So `char x[]` is equivalent to `char *x` and in the same sense `char *x[]` is equivalent to `char **x`. – Iharob Al Asimi Mar 04 '18 at 18:11
  • @ynn; Here you go: https://port70.net/~nsz/c/c11/n1570.html#6.3.2.1p3 – haccks Mar 04 '18 at 18:15
  • @haccks Thank you. I've known `*a`, `a[]` and `a[10]` are the same, but didn't know the same can be applied in my case. I think the general definition is written in the standard, so I'll search for the topic at the website you told me. – ynn Mar 04 '18 at 18:29
1

The questions you linked apply to array declarations made outside of function parameter lists. It is true that outside of function parameter lists char *argv[] declaration is very different from char **argv declaration. The former declares an array, while the latter declares a pointer.

However, function parameter declarations are treated very differently, and the questions you linked do not apply to function parameter declarations. When array declaration syntax is used to declare a function parameter, the array type is automatically transformed into pointer type. So, in function parameter list char *argv[] declaration is transformed into char **argv declaration. In that sense these declarations are fully equivalent in that context. In both cases you end up with a pointer, which is modifiable.

From more general point of view, in C, even in function parameter lists the array syntax is not exactly equivalent to pointer syntax since array syntax requires the element type to be complete

struct S;
void foo(struct S s[]); /* invalid in C */
void bar(struct S *s);  /* OK in C */
AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
0

As far as I know there's none. In both cases argv is of type char **. Which means it is a pointer to pointer

Wylfryd
  • 65
  • 1
  • 7
  • 2
    It's not a multidimensional array. –  Mar 04 '18 at 18:32
  • Isn't `char **` equivalent to `char [][]` ? Both versions are allowed by the compiler. – Wylfryd Mar 04 '18 at 18:35
  • Where do you think the compiler allows `char [][]` at all? Or did you mean `char [][20]`, which is allowed in some contexts? – Jonathan Leffler Mar 04 '18 at 18:39
  • True, I meant the second one. Still, could you explain the difference? I thought that pointer to pointer type resulted in multidimensional array. – Wylfryd Mar 04 '18 at 18:45