473,473 Members | 1,637 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

char* argv[]

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]);
}
Dec 14 '07 #1
24 3175
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
Dec 14 '07 #2
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[]?
Dec 14 '07 #3
Logan said:

<snip>
Is char **argv equal to char *argv[]?
In this context (formal parameters in a function declaration), yes, they
are equivalent.

--
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
Dec 14 '07 #4
Logan wrote:
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
Dec 14 '07 #5
Richard Heathfield <rj*@see.sig.invalidwrites:
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.
--
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa6 7f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}
Dec 14 '07 #6
Logan <Lo*********@student.uts.edu.auwrites:
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.
--
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa6 7f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}
Dec 14 '07 #7
>The first program is otherwise correct (although non-robust, since it
assumes that argc is at least 1)
argc will always be atleast one.

On Dec 15, 4:30 am, Richard Heathfield <r...@see.sig.invalidwrote:
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.
Dec 15 '07 #8
sr*************@gmail.com wrote:
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.
--
pete
Dec 15 '07 #9
sr*************@gmail.com said:
Richard Heathfield wrote:
>>The first program is otherwise correct (although non-robust, since it
assumes that argc is at least 1)

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

--
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
Dec 15 '07 #10
Richard Heathfield wrote:
sr*************@gmail.com said:
>Richard Heathfield wrote:
>>The first program is otherwise correct (although non-robust, since it
assumes that argc is at least 1)
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".
What is the case (are the cases) for argc == 0?

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Dec 15 '07 #11
In article <xt******************************@comcast.com>,
Joe Wright <jo********@comcast.netwrote:
>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
--
:wq
Dec 15 '07 #12
On Sat, 15 Dec 2007 10:20:24 +1100, Logan
<Lo*********@student.uts.edu.auwrote:
>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
Dec 19 '07 #13
On Sat, 15 Dec 2007 10:30:55 +1100, Logan
<Lo*********@student.uts.edu.auwrote:
>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
Dec 19 '07 #14
Barry Schwarz said:
Logan wrote:
<snip>
>>int main(int argc, char *argv[]) {
printf("%s", argv[0]);
}

argv is an array of pointers.
No, it's a pointer to the first element in an array of pointers.

--
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
Dec 19 '07 #15
Barry Schwarz <sc******@doezl.netwrites:
On Sat, 15 Dec 2007 10:30:55 +1100, Logan
<Lo*********@student.uts.edu.auwrote:
[...]
>>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.

--
Keith Thompson (The_Other_Keith) <ks***@mib.org>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Dec 19 '07 #16
On Dec 14, 11:30 pm, Richard Heathfield <r...@see.sig.invalidwrote:
Logan said:
int main(int argc, char *argv) {
<snip>
>
Your second program thinks argv is a string, which it isn't.
No. In the second program, argv is a pointer to
an array of characters. C doesn't have a string type.

Dec 19 '07 #17
William Pursell said:
On Dec 14, 11:30 pm, Richard Heathfield <r...@see.sig.invalidwrote:
>Logan said:
int main(int argc, char *argv) {
<snip>
>>
Your second program thinks argv is a string, which it isn't.

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

--
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
Dec 19 '07 #18
Richard Heathfield <rj*@see.sig.invalidwrites:
William Pursell said:
>On Dec 14, 11:30 pm, Richard Heathfield <r...@see.sig.invalidwrote:
>>Logan said:
int main(int argc, char *argv) {
<snip>
>>>
Your second program thinks argv is a string, which it isn't.

No.

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
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).
>C doesn't have a string type.

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.

--
Keith Thompson (The_Other_Keith) <ks***@mib.org>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Dec 19 '07 #19
Keith Thompson said:

<snip>
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>

--
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
Dec 19 '07 #20
Richard Heathfield <rj*@see.sig.invalidwrites:
Keith Thompson said:

<snip>
>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.
(And a pointer to the first character in a string may legitimately be
referred to as a pointer to the string -- which would not be the case
if "string" were a data type.)

But the program isn't actually doing that. Both versions had

printf("%s", argv[0]);

which treats argv[0], not argv, as a pointer to (the first character
of) a string. One version declared argv as ``char *argv'', but that
by itself doesn't imply that argv is a pointer to a string; it could
point to a single character, or to the first element of an array of
characters none of which are '\0'.

--
Keith Thompson (The_Other_Keith) <ks***@mib.org>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Dec 19 '07 #21
Keith Thompson said:
Richard Heathfield <rj*@see.sig.invalidwrites:
>Keith Thompson said:

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

(And a pointer to the first character in a string may legitimately be
referred to as a pointer to the string
I have never been very comfortable with that terminology...
-- which would not be the case
if "string" were a data type.)
....and that's why. Those people who - incorrectly but nevertheless quite
understandably - think of "string" as a synonym for "array of characters
terminated by the first null character" run the risk of mentally
translating "pointer to string" to "pointer to array", and suddenly
they're not only incorrect but in danger of confusing two legitimate
terminologies.
>
But the program isn't actually doing that. Both versions had

printf("%s", argv[0]);
Blargh! It gets worse? I didn't even notice the [0]! Possibly because it
looks so natural in context.

--
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
Dec 19 '07 #22
On Dec 19, 7:36 am, Richard Heathfield <r...@see.sig.invalidwrote:
William Pursell said:
On Dec 14, 11:30 pm, Richard Heathfield <r...@see.sig.invalidwrote:
Logan said:
int main(int argc, char *argv) {
<snip>
Your second program thinks argv is a string, which it isn't.
No.

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.
A pointer to an array of characters is a pointer to
the first element.
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.
What the program does with the argument is irrelevant. From
the declaration, the compiler determines that the
argument is a pointer to a character.
C doesn't have a string type.

Non sequitur. I didn't claim that C has a string type.
You stated: "Your second program thinks argv is a string"
What does that mean? As far as I know, programs are
not capable of thought, so that sentence must mean
that the compiler interprets the declaration as
declaring that the argument is a string. It
follows that the author of the sentence, (you)
believe that the compiler has some concept of
what a string is. (Of course I realize you
don't think that C has a string type. But
I believe your sentence could be interpreted
that way, and should be clarified. Well,
actually, I was just giving you some good-natured
ribbing.)
Dec 19 '07 #23
William Pursell said:

<snip>
A pointer to an array of characters is a pointer to
the first element.
No, it isn't; they have different types, as this program will demonstrate.

#include <stdio.h>

int main(void)
{
char arr[13] = "Hello, world"; /* array of characters */
char (*parr)[13] = &arr; /* pointer to array of characters */
char *pch = arr; /* ptr to first element, eqvt to &arr[0] */
printf("%lu\n", (unsigned long)sizeof *parr);
printf("%lu\n", (unsigned long)sizeof *pch);
return 0;
}

--
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
Dec 19 '07 #24
Barry Schwarz wrote, On 19/12/07 04:19:
On Sat, 15 Dec 2007 10:20:24 +1100, Logan
<Lo*********@student.uts.edu.auwrote:
>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.
Well, it would be if char *argv was the correct type for the parameter.
However, the second parameter should have been "char **argv" or "char
*argv[]".
What type of parameter must you use to match a %s?
Trying to use argv would also be wrong, because the prototype for main
is wrong.
--
Flash Gordon
Dec 20 '07 #25

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

10
by: JKop | last post by:
Why isn't: int main(int argc, char* argv) { /* ... */ } as: int main(int argc, const char* argv)
21
by: Bret | last post by:
I'm curious why char** argv is acceptable in the main() declaration. In the comp.lang.c FAQ (question 6.18) it says that pointers to pointers and pointers to an array are not interchangable. ...
10
by: David | last post by:
what's the differences between: int main(int argc,char* argv){ ... } and: int main(int argc,char** argv){ ...
14
by: Hal Styli | last post by:
Is this a style thing? int main(int argc, char *argv ) or int main(int argc, char **argv ) i.e. *argv or **argv Why choose the latter?
7
by: =?Utf-8?B?Vmlu?= | last post by:
Hi, I have a question. I created a simple executable program using Visual C++ from Visual Studio 6.0 This program is called from a script that passes in one argument. Now, my question is: ...
8
by: oogie | last post by:
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...
12
by: kevin.eugene08 | last post by:
Hello all, Forgive the somewhat simple question I am sure this will be, but I am having some problem understanding what: char **argv looks like. For instance, i know through trial and error...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.