char** argv versus char *argv[]

O

oogie

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.
 
A

Alf P. Steinbach

* oogie:
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];
}

Have you tried putting this to your compiler?

Cheers, & hth.,

- Alf
 
W

werasm

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];
}

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




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.
 
R

Ron Natalie

oogie said:
Hi,

The arguments to main are usually passed as char* argv[] or char **
argv,

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.
 
R

Ron Natalie

werasm said:
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"
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.
 
O

oogie

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

Andrey Tarasevich

Ron said:
...
The arguments to main are usually passed as char* argv[] or char **
argv,

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.

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

Andrey Tarasevich

werasm said:
...
- 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** ){ }
...

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.
 
W

werasm

werasm said:
...
- 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** ){ }
...

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.

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
 
D

Default User

werasm wrote:

Sorry, rephrase:

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

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,996
Messages
2,570,238
Members
46,826
Latest member
robinsontor

Latest Threads

Top