char* argv[]

L

Logan

Why (I) works but (II) gives segmentation error?

(I)
int main(int argc, char *argv[]) {
printf("%s", argv[0]);
}

(II)
int main(int argc, char *argv) {
printf("%s", argv[0]);
}
 
R

Richard Heathfield

Logan said:
Why (I) works but (II) gives segmentation error?

(I)
int main(int argc, char *argv[]) {
printf("%s", argv[0]);
}

(II)
int main(int argc, char *argv) {
printf("%s", argv[0]);
}

The behaviour of both programs is undefined, because you don't have a
prototype in scope for printf, which is a variadic function.

The first program is otherwise correct (although non-robust, since it
assumes that argc is at least 1), although adding a return statement with
an appropriate return value would be wise.

The second program incorrectly describes the second parameter of main. The
two correct forms of main are:

int main(void) /* or any exact semantic equivalent */
int main(int argc, char **argv) /* or any exact semantic equivalent */

Your second program thinks argv is a string, which it isn't.
 
L

Logan

Fri, 14 Dec 2007 23:30:39 +0000¿¡, Richard Heathfield ½è½À´Ï´Ù:
Logan said:
Why (I) works but (II) gives segmentation error?

(I)
int main(int argc, char *argv[]) {
printf("%s", argv[0]);
}

(II)
int main(int argc, char *argv) {
printf("%s", argv[0]);
}

The behaviour of both programs is undefined, because you don't have a
prototype in scope for printf, which is a variadic function.

The first program is otherwise correct (although non-robust, since it
assumes that argc is at least 1), although adding a return statement with
an appropriate return value would be wise.

The second program incorrectly describes the second parameter of main. The
two correct forms of main are:

int main(void) /* or any exact semantic equivalent */
int main(int argc, char **argv) /* or any exact semantic equivalent */

Your second program thinks argv is a string, which it isn't.

Is char **argv equal to char *argv[]?
 
D

Default User

Logan said:
Why (I) works but (II) gives segmentation error?

(I)
int main(int argc, char *argv[]) {
printf("%s", argv[0]);
}

(II)
int main(int argc, char *argv) {
printf("%s", argv[0]);
}


Why do you think they are the same? In case II, argv is a pointer to
char (not a Standard signature for main()). Dereferencing that gives
you a single character. You then pass it to printf when it expects a
pointer to char.




Brian
 
B

Ben Pfaff

Richard Heathfield said:
Logan said:
(I)
int main(int argc, char *argv[]) {
printf("%s", argv[0]);
}

The behaviour of both programs is undefined, because you don't have a
prototype in scope for printf, which is a variadic function.

The first program is otherwise correct (although non-robust, since it
assumes that argc is at least 1), although adding a return statement with
an appropriate return value would be wise.

It also fails to write a new-line to stdout to complete the
output line, although I suppose argv[0] could theoretically end
in a new-line.
 
B

Ben Pfaff

Logan said:
Is char **argv equal to char *argv[]?

In a function prototype, they are semantically equivalent. The
latter suggests to human readers that the argument is an array,
but the compiler will treat the two declarations identically.
 
S

srikrishanmalik

The first program is otherwise correct (although non-robust, since it
assumes that argc is at least 1)

argc will always be atleast one.

Logan said:
Why (I) works but (II) gives segmentation error?
(I)
int main(int argc, char *argv[]) {
printf("%s", argv[0]);
}
(II)
int main(int argc, char *argv) {
printf("%s", argv[0]);
}

The behaviour of both programs is undefined, because you don't have a
prototype in scope for printf, which is a variadic function.

The first program is otherwise correct (although non-robust, since it
assumes that argc is at least 1), although adding a return statement with
an appropriate return value would be wise.

The second program incorrectly describes the second parameter of main. The
two correct forms of main are:

int main(void) /* or any exact semantic equivalent */
int main(int argc, char **argv) /* or any exact semantic equivalent */

Your second program thinks argv is a string, which it isn't.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999

The first program is otherwise correct (although non-robust, since it
assumes that argc is at least 1)

argc will always be atleast one.
 
P

pete

argc will always be atleast one.

That's not what the C standard says.

N869
5.1.2.2 Hosted environment
5.1.2.2.1 Program startup

[#2] If they are declared, the parameters to the main
function shall obey the following constraints:

-- If the value of argc is greater than zero, the string
pointed to by argv[0] represents the program name;
argv[0][0] shall be the null character if the program
name is not available from the host environment. If
the value of argc is greater than one, the strings
pointed to by argv[1] through argv[argc-1] represent
the program parameters.
 
R

Richard Heathfield

(e-mail address removed) said:
argc will always be atleast one.

This is not guaranteed by the Standard. See 2.1.2.2 of C89 or 5.1.2.2.1 of
C99.

It is generally a good idea to check your facts before issuing a
"correction".
 
J

Joe Wright

Richard said:
(e-mail address removed) said:


This is not guaranteed by the Standard. See 2.1.2.2 of C89 or 5.1.2.2.1 of
C99.

It is generally a good idea to check your facts before issuing a
"correction".
What is the case (are the cases) for argc == 0?
 
R

Richard Tobin

What is the case (are the cases) for argc == 0?

An operating system that doesn't provide, or allows you not to provide,
any argv values.

The version of unix I'm using says that the exec*() functions require
at least one argument, but POSIX merely says that the first argument
should be the filename.

-- Richard
 
B

Barry Schwarz

Why (I) works but (II) gives segmentation error?

(I)
int main(int argc, char *argv[]) {
printf("%s", argv[0]);
}

argv is an array of pointers. argv[0] is the first pointer in the
array.
(II)
int main(int argc, char *argv) {
printf("%s", argv[0]);
}

argv is a pointer to char. argv[0] is the char itself.

What type of parameter must you use to match a %s?


Remove del for email
 
B

Barry Schwarz

Fri, 14 Dec 2007 23:30:39 +0000¿¡, Richard Heathfield ½è½À´Ï´Ù:
Logan said:
Why (I) works but (II) gives segmentation error?

(I)
int main(int argc, char *argv[]) {
printf("%s", argv[0]);
}

(II)
int main(int argc, char *argv) {
printf("%s", argv[0]);
}

The behaviour of both programs is undefined, because you don't have a
prototype in scope for printf, which is a variadic function.

The first program is otherwise correct (although non-robust, since it
assumes that argc is at least 1), although adding a return statement with
an appropriate return value would be wise.

The second program incorrectly describes the second parameter of main. The
two correct forms of main are:

int main(void) /* or any exact semantic equivalent */
int main(int argc, char **argv) /* or any exact semantic equivalent */

Your second program thinks argv is a string, which it isn't.

Is char **argv equal to char *argv[]?

Only in certain contexts. With three exceptions, an expression (not a
declaration) with array type is converted to the address of the first
element with type pointer to element type.

So immediately you know that
char *argv1[10];
char **argv2;
produce very different type of objects.

However, given the above
argv2 = argv1;
is legal and is exactly equivalent to
argv2 = &argv1[0];

In the case of a function declaration, the actual arguments are
"passed" to the formal parameters as if by assignment. Consequently,
even if your parameter list specifies an array, the compiler knows
better and generates code to process the pointer that is actually
passed.

This is the reason that
char *x1 = "Hello,";
char x2[] = " world";
printf("%s%s\n", x1, x2)
works even though x1 is a pointer and x2 is an array.


Remove del for email
 
K

Keith Thompson

Barry Schwarz said:
On Sat, 15 Dec 2007 10:30:55 +1100, Logan
Is char **argv equal to char *argv[]?

Only in certain contexts. With three exceptions, an expression (not a
declaration) with array type is converted to the address of the first
element with type pointer to element type.

So immediately you know that
char *argv1[10];
char **argv2;
produce very different type of objects.

However, given the above
argv2 = argv1;
is legal and is exactly equivalent to
argv2 = &argv1[0];

In the case of a function declaration, the actual arguments are
"passed" to the formal parameters as if by assignment. Consequently,
even if your parameter list specifies an array, the compiler knows
better and generates code to process the pointer that is actually
passed.

This is the reason that
char *x1 = "Hello,";
char x2[] = " world";
printf("%s%s\n", x1, x2)
works even though x1 is a pointer and x2 is an array.

There are actually two independent language rules in play here.

The one you describe (that an expression of array type is
automatically converted to a pointer in most contexts) says nothing
about declarations such as ``char **argv'' or ``char *argv[]''.

There's a separate special rule for parameter declarations that says
that something that looks like an array parameter declaration is
really a pointer declaration. Note that this rule doesn't involve any
(run-time) type conversions; it describes two constructs as being
exactly equivalent.

These two rules work together to allow lazy programmers to pretend
that arrays and pointers are the same thing.

The array-to-pointer conversion rule is almost impossible to avoid.
The parameter declaration rule can be avoided (and IMHO should be)
simply by declaring parameters as pointers.
 
R

Richard Heathfield

William Pursell said:

Your "correction" is incorrect.
In the second program, argv is a pointer to
an array of characters.

No, in the second program argv is (incorrectly defined as) a pointer to the
*first element* in an array of characters. The program then uses this
value as an argument matching a printf %s format specifier - in other
words, the program thinks argv is a string (just as I claimed), and is
using it as one.
C doesn't have a string type.

Non sequitur. I didn't claim that C has a string type.
 
K

Keith Thompson

Richard Heathfield said:
William Pursell said:

Your "correction" is incorrect.


No, in the second program argv is (incorrectly defined as) a pointer to the
*first element* in an array of characters. The program then uses this
value as an argument matching a printf %s format specifier
Right.

- in other
words, the program thinks argv is a string (just as I claimed), and is
using it as one.

Nope. argv is a pointer. A string is "a contiguous sequence of
characters terminated by and including the first null character".
A pointer cannot be a string. [*]

Quoting the program in the orginal post:

| (I)
| int main(int argc, char *argv[]) {
| printf("%s", argv[0]);
| }
|
| (II)
| int main(int argc, char *argv) {
| printf("%s", argv[0]);
| }

Neither program assumes that argv is either a string or a pointer to a
string. Both programs assume (in their respective printf calls) that
``argv[0]'' is *a pointer to* a string (defined by the standard as "a
pointer to its initial (lowest addressed) character" of a string). In
the first program, this assumption is correct if argc is greater than
zero. In the second program, this assumption is incorrect; argv[0] is
a single char (assuming the implementation allows the rather odd
declaration of main).
Non sequitur. I didn't claim that C has a string type.

But it does define precisely what a string is.

[*] Well, I suppose a pointer could be a string if its representation,
as a sequence of bytes, happens to include a null byte, but that's not
what was meant.
 
R

Richard Heathfield

Keith Thompson said:

A pointer cannot be a string. [*]

I have been out-nitted. Yes, of course I mean that the program is treating
argv as a pointer to the first character in a string.

<snip>
 

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,769
Messages
2,569,581
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top