I've seen char **argv and char *argv[] and am curious which is correct. Or
are either correct?
--
.*. Where feelings are concerned, answers are rarely simple [GeneDeWeese]
-() < When I go to the theater, I always go straight to the "bag and mix"
`*' bulk candy section...because variety is the spice of life... [me]
Paul Derbyshire ao...@freenet.carleton.ca, http://chat.carleton.ca/~pderbysh
They are both technically correct. I have heard of some compilers that
barf when you use char *argv[], although I have never had this happen to
me.
--
---------------------------------------------------------------------
| John M. Aldrich, aka Fighteer I | mailto:figh...@cs.com |
| * Proud user of DJGPP! * | http://www.cs.com/fighteer |
| ObJoke: If Bill Gates were a robber, not only would he |
| shoot you, but he'd send you a bill for the bullets. |
---------------------------------------------------------------------
On 8 Jun 1997, Paul Derbyshire wrote:
> I've seen char **argv and char *argv[] and am curious which is correct. Or
> are either correct?
AFAIK, the difference is only important when you declare argv. Since
these are passed to your `main' function, and are therefore declared
elsewhere (in the library sources), both forms are correct.
They are both the same thing. The array syntax is interchangable with
pointer
arithmetic. Or at least should be if the compiler in question follows the
language
at all.
Personally I have only ever used *argv[]
There may be compilers out there that won't accept **argv, but if they
don't then
I wouldn't use them since they'd probably have other problems.
I don't think either is more correct than the other, although *argv[] is
most
certainly used more.
.
>I don't think either is more correct than the other, although *argv[] is
>most
>certainly used more.
The *argv[] is used more probably because it is safer. Why?
A basic example:
void func1 (int *p);
void func2 (int p[]);
Both func1 and func2 accept pointers to ints as arguments. But they are
not exactly the same. The func2 takes a pointer that is constant, i.e.
you'll get warnings when you try to modify its value.
uh-um ... what does that mean? no offense, but where exactly do you get
the notion that
void func2(int p[])
{
p[0] = 42;
return;
}
will generate a warning? these types of discussions belong in
comp.lang.c (and probably they are in the C FAQ.)
--
Sinan
*******************************************************************
A. Sinan Unur WWWWWW
|--O+O
mailto:sinan...@cornell.edu C ^
http://www.people.cornell.edu/pages/asu1/ \ ~/
Unsolicited e-mail is _not_ welcome, and will be billed for.
*******************************************************************
> The *argv[] is used more probably because it is safer. Why?
>A basic example:
> void func1 (int *p);
> void func2 (int p[]);
>Both func1 and func2 accept pointers to ints as arguments. But they are
>not exactly the same. The func2 takes a pointer that is constant, i.e.
>you'll get warnings when you try to modify its value.
Maybe I misunderstood what you said, but gcc reports no errors with this program
compiled with "gcc -Wall test.c":
int *Func1(int *Pointer)
{
Pointer += 5;
Pointer[5] = 10;
return Pointer;
}
int *Func2(int Pointer[])
{
Pointer += 5;
Pointer[5] = 10;
return Pointer;
}
int main(void)
{
int Variable[100];
Func1(Variable);
Func2(Variable);
return 1;
}
Note that both functions modify the pointer and place information into the
array. Did I misunderstand what you were saying?
>> I've seen char **argv and char *argv[] and am curious which is correct
Or
>> are either correct?
> They are both the same thing. The array syntax is interchangable with
> pointer
> arithmetic. Or at least should be if the compiler in question follows
the
> language at all.
Not exact. The are both the same thing only when used as parameters
to functions (like in main).
char* argv1[] (not as a parameter) is an array of pointer
variables.
char** argv2 (always) is a pointer (variable holding the address of) a
pointer-to-char.
for example :
extern char* argv1[]; /* declares array of pointers. */
extern char **argv2;
argv1++; // ERROR this is an array !!
argv2++; // OK.
so there is difference.
Eyal.
> I've seen char **argv and char *argv[] and am curious which is correct. Or
> are either correct?
Either is correct although since I have encountered compilers which
generate incorrect code for parameters which are arrays I always code
function parameters as pointers when I will be receiving an array.
Therefore, in the case of argv, I use 'char **argv' to avoid problems
porting.
Art S. Kagel, ka...@bloomberg.com
According to my C reference and my understanding of the language, when
you specify empty brackets for an array-type variable in an argument
list, the compiler handles the variable identically to one explicitly
defined as a pointer. In essence, *[] and ** have identical
functionality. A little bird once told me that *argv[] was not 100%
portable; however, I've never seen a problem with it.
--
---------------------------------------------------------------------
| John M. Aldrich, aka Fighteer I | mailto:figh...@cs.com |
| Proud owner of what might one | http://www.cs.com/fighteer |
| day be a spectacular MUD... | Plan: To make Bill Gates suffer |
---------------------------------------------------------------------
>Not exact. The are both the same thing only when used as parameters
>to functions (like in main).
>
Is it also true that argv[argc] == NULL
with all compilers?
Hans
According to the ANSI\ISO standard, you may always access one element
past the end of an array. Since argc is always one bigger than the
highest element of argv, argv[argc] will indeed always work.
--
Jason Daniels -- bd...@rgfn.epcc.edu
---> BELIEVE THE LIE <---
Linux: The choice of a GNU generation.
Winblows 95: The world's best-selling computer virus.
: uh-um ... what does that mean? no offense, but where exactly do you get
: the notion that
: void func2(int p[])
: {
: p[0] = 42;
: return;
: }
I think the original implication was that
void test(int p[])
{
p++;
}
would create a warning, which still isn't true. The analogy is, of course,
with:
void test()
{
int p[5];
p++;
}
being incorrect.
--
George Foot <mert...@sable.ox.ac.uk>
Merton College, Oxford
> I guess they mean exactly the same, because declaring a variable int a[]
> is pretty equal to declaring int ** a.
Be careful about this; pointers and arrays are _not_ the same. They can
be manipulated in a few different ways, but they are _not_ identical.
> I've seen char * argv[] and
> char** argv being used many times without problems. I think they are
> also compiled in the same way, but maybe you should try to compile to
> assembly code to figure it out.
. . . except in the case of function arguments. A function with an
argument of a single-dimensioned array is treated in all ways identically
to a pointer. That is, a function with prototype
f(int ai[]);
is treated precisely the same as one with prototype
f(int *ai);
Since main is just another function, this applies to it as well. Either
char **argv (pointer to pointer to char) or char *argv[] (array of pointer
to char) are both treated the same, and so both are legal. (Note that
char (*argv)[], or pointer to array of char, would be illegal.)
--
Erik Max Francis, &tSftDotIotE / email / m...@alcyone.com
Alcyone Systems / web / http://www.alcyone.com/max/
San Jose, California, United States / icbm / 37 20 07 N 121 53 38 W
\
"Covenants without the sword / are but words."
/ Camden
The ANSI draft says that, yes.
> uh-um ... what does that mean? no offense, but where exactly do you get
> the notion that
...
> will generate a warning? these types of discussions belong in
> comp.lang.c (and probably they are in the C FAQ.)
He was claiming that the array name of an array argument is not a
modifiable lvalue, which is a different thing. This in, however,
incorrect.
> The *argv[] is used more probably because it is safer. Why?
> A basic example:
> void func1 (int *p);
> void func2 (int p[]);
> Both func1 and func2 accept pointers to ints as arguments. But they are
> not exactly the same. The func2 takes a pointer that is constant, i.e.
> you'll get warnings when you try to modify its value.
No, you won't. The ANSI C specification specifically states that an array
argument decays to a pointer argument. No implicit consts are introduced
by the compiler. As such, the following function is perfectly legal:
void f(int a[])
{
static int x;
a = &x;
}
The reason is because arrays are automatically treated as pointers in
function arguments, so this function is in fact treated as
void f(int *a) /* ... */
and as such using the argument as an lvalue is perfectly legal. (Perhaps
not very useful, though, because its value is only being changed within
the function.)
Your statement is tantamount to stating that the int a[] argument would be
silently treated as a int *const, which is not correct.
> They are both the same thing. The array syntax is interchangable with
> pointer
> arithmetic. Or at least should be if the compiler in question follows
> the
> language
> at all.
Be careful with such statements. Arrays and pointers are _not_ the same
thing. In function arguments, however, an argument of array type is
silently treated as an argument of pointer type. So char **argv and char
*argv[] are precisely the same.
That only applies to function arguments, however; arrays and pointers are
different entities.
> Is it also true that argv[argc] == NULL
> with all compilers?
Yes. "argv[argc] shall be a null pointer" (5.1.2.2.1).
>>> I've seen char **argv and char *argv[] and am curious which is correct
>Or
>>> are either correct?
>> They are both the same thing. The array syntax is interchangable with
>> pointer
>> arithmetic. Or at least should be if the compiler in question follows
>the
>> language at all.
>Not exact. The are both the same thing only when used as parameters
>to functions (like in main).
>char* argv1[] (not as a parameter) is an array of pointer
>variables.
>char** argv2 (always) is a pointer (variable holding the address of) a
>pointer-to-char.
>for example :
>extern char* argv1[]; /* declares array of pointers. */
>extern char **argv2;
>argv1++; // ERROR this is an array !!
>argv2++; // OK.
>so there is difference.
On the other hand you can use pointers as arrays (if they have
dynamically allocated space, so you could do:
x=*argv1[1]; // and
x=*argv2[1];
In fact I believe arrays are treated exactly like pointers, and as you
can see from the example, pointers can be indexed as arrays...
So in fact there's not much difference between arrays and pointers,
and none at all when used as arguments for main().