char** argv versus char *argv[]

char** argv versus char *argv[]

Post by oogi » Sun, 18 Nov 2007 23:33:32


Hi,

The arguments to main are usually passed as char* argv[] or char **
argv, where for this example argv is the array of arguments. What I
don't understand is how accessing the actual argument value evaluates
to the following:

int main(int argc, char** argv)
{
char ch = argv[0];
}

or

int main(int argc, char *argv[])
{
char *ch = argv[0];
}

I do get the logic behind the latter case, but char** argv really
puzzles. Any help would be appreciated.
 
 
 

char** argv versus char *argv[]

Post by Alf P. Ste » Sun, 18 Nov 2007 23:36:48

* oogie:

Have you tried putting this to your compiler?

Cheers, & hth.,

- Alf

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

 
 
 

char** argv versus char *argv[]

Post by weras » Mon, 19 Nov 2007 01:02:56


Besides not compiling, I can comment on this.

- char[] decays to char* during a function call.

In this case:
int main( int argc, char* argv[] ){}

is equivalent to this:
int main( int argc, char** ){ }

The reason for this is explained in Section 13.1 of c++98 standard:
"Parameter declarations that differ only in pointer * versus array[]
are equivalent"

Therefore this is exactly the same - in both cases an array
of NULL terminated strings.

Regards,

Werner
 
 
 

char** argv versus char *argv[]

Post by Ron Natali » Mon, 19 Nov 2007 02:27:33


As far as the type of a function is concerned an array is always
converted to a pointer to the first element. The type of main
(DESPITE the text of the standard) here is int main(int, char**).

The difference between the two forms just like the presence or
absence of top level const doesn't matter external to the function
just internal.
 
 
 

char** argv versus char *argv[]

Post by Ron Natali » Mon, 19 Nov 2007 02:32:05


That's for overloading (main is one of the only function in C++ that's
inversely overloaded....i.e., you give one and the implemenation shapes
the call to match).

The important clause is 8.3.5 (3) where parameters and return types of
type array of are converted to pointer to determine the type of the
function.
 
 
 

char** argv versus char *argv[]

Post by oogi » Mon, 19 Nov 2007 03:15:28

Thanks for pointing out that the code wouldn't compile, it definitely
cleared things up.
 
 
 

char** argv versus char *argv[]

Post by Andrey Tar » Mon, 19 Nov 2007 06:22:12


Err... And what would be the _internal_ difference between a 'char*[]' parameter
and a 'char **' parameter?

--
Best regards,
Andrey Tarasevich
 
 
 

char** argv versus char *argv[]

Post by Andrey Tar » Mon, 19 Nov 2007 06:26:47


Strictly speaking, this has absolutely nothing to do with any function calls.
When used in the function parameter declaration, declarator 'T p[N]' is
equivalent to the 'T p[]' and is equivalent to the 'T* p'. One can think of them
as "decaying" into each other at purely syntactical level. No "calls" necessary.

--
Best regards,
Andrey Tarasevich
 
 
 

char** argv versus char *argv[]

Post by weras » Mon, 19 Nov 2007 07:12:26

On Nov 17, 10:26 pm, Andrey Tarasevich < XXXX@XXXXX.COM >



Sorry, rephrase:

- char[] decays to char* during a function declaration. Is this
better?

My main point was to indicate to the OP that in a function
declaration a parameter "char [] or char [N]" does not have
the same type as char [N], but has the type char* (or decays
to char*). I should not have said "during a call" as this
was not what I meant.

As a small example:

void foo( char param[] )
{
++param; //Compiles fine...

char array[10];
++array; //Fails to compile!
}

Regards,

Werner
 
 
 

char** argv versus char *argv[]

Post by Default Us » Mon, 19 Nov 2007 12:57:32


No. The two forms are equivalent, there is no conversion or "decay".
That is something that happens when a function is called, not when
declared. Actually, it's that the name of an array is implicitly
converted to a pointer in most cases, exceptions including the
address-of operator and the sizeof operator.

If a size is included in a declaration, it's ignored, so:

void f(char *p);
void f(char p[]);
void f(char p1000]);

Are all equivalent declarations.

The only other place char[] is legal is when used as a declaration with
an initializer, no conversion there either.




Brian