Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

parsing practice

3 views
Skip to first unread message

Bill Cunningham

unread,
Mar 10, 2010, 5:50:47 PM3/10/10
to
This simple little program takes from stdin and writes to stdout. No
other streams are involved. Why am I segmentation faulting? I am guessing it
has something to do with the argc==0 part of the program but I don't know
how I should change it.
All characters on each line should begin with an '+' otherwise the
characters aren't printed or in this case an error is triggered.

Bill#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
if (argc == 0) {
fprintf(stderr, "parsing usage error\n");
return 1;
}
if (*argv[1] == '+') {
puts("good + found\n");
return 0;
} else {
if (*argv[1] != '+') {
fputs("error + not found\n", stderr);
return 1;
}
return 0;

}
return 0;
}


Ike Naar

unread,
Mar 10, 2010, 5:59:49 PM3/10/10
to
In article <4b982248$0$12444$bbae...@news.suddenlink.net>,

Bill Cunningham <nos...@nspam.invalid> wrote:
>#include <stdio.h>
>#include <string.h>
>
>int main(int argc, char *argv[])
>{
> if (argc == 0) {
> fprintf(stderr, "parsing usage error\n");
> return 1;
> }

For the next line to work, argc should be at least 2;
nonzero is not good enough.

Bill Cunningham

unread,
Mar 10, 2010, 6:30:37 PM3/10/10
to

"Ike Naar" <i...@localhost.claranet.nl> wrote in message
news:hn9895$6f2$2...@news.eternal-september.org...

> For the next line to work, argc should be at least 2;
> nonzero is not good enough.

I'm not quite understanding here. "Nonzero is not good enough." If there
are no argc's I want the program to terminate with the "usage error" error.
As long as it is nonzero I am happy. I'm stuck on this one.

Bill


Ian Collins

unread,
Mar 10, 2010, 6:31:22 PM3/10/10
to

What happens if argc == 1?

--
Ian Collins

Dave Hansen

unread,
Mar 10, 2010, 6:37:17 PM3/10/10
to

It's how array indexing works.

If argc is zero, you cannot access any elements of argv.

If argc is 1, you may only access argv[0].

If you want to access argv[1], argc must be at least 2.

Note: argv[0] is often the string that invoked the program itself. I
don't think you'll ever see argc==0.

Regards,

-=Dave

Ike Naar

unread,
Mar 10, 2010, 6:37:57 PM3/10/10
to
In article <4b982b9f$0$12429$bbae...@news.suddenlink.net>,

If argc = 1, argv[0] is a valid string but argv[1] = NULL.
You wouldn't want to dereference argv[1] in that case.

James Harris

unread,
Mar 10, 2010, 6:38:26 PM3/10/10
to

Try an experiment to find how your program is started:

int main(int argc, char *argv[]) {

printf("argc = %d\n", argc);
}

Try running this with a varying number of arguments to see how argc is
calculated. Then you can add a loop to print the argv values. This
should help you see how the arg values are used - which should resolve
your original problem.

James

Nick

unread,
Mar 11, 2010, 3:15:44 AM3/11/10
to
"Bill Cunningham" <nos...@nspam.invalid> writes:

> This simple little program takes from stdin and writes to stdout.

No it doesn't. It never touches stdin.

It uses the parameters passed in argv, but that's nothing at all to do
with "taking from stdin".
--
Online waterways route planner | http://canalplan.eu
Plan trips, see photos, check facilities | http://canalplan.org.uk

Robbie Hatley

unread,
Mar 11, 2010, 3:36:21 AM3/11/10
to

"Bill Cunningham" wrote:

> #include <stdio.h>
> #include <string.h>
>
> int main(int argc, char *argv[])
> {
> if (argc == 0) {
> fprintf(stderr, "parsing usage error\n");
> return 1;
> }
> if (*argv[1] == '+') {
> puts("good + found\n");
> return 0;
> } else {
> if (*argv[1] != '+') {
> fputs("error + not found\n", stderr);
> return 1;
> }
> return 0;
>
> }
> return 0;
> }

According to section 5.1.2.2.1 of the C standard:
- argc must be non-negative
- argv[argc] must be a null pointer
- if argc is greater than zero, then argv[0] is NOT an argument,
it's the name of the program, or an empty string if the program
name is not available.
- if argc is greater than one, argv[1] through argv[argc-1]
will be your program parameters.

In other words, argc is "count of items in argv", NOT "count of
arguments". And since the zeroeth element of argc is always
reserved for the program name (whether it's available or not),
if argc is non-zero, argc = "number of arguments + 1".

(The standard doesn't mention under what conditions argc
is 0. I've never seen argc==0 in my life. I suppose
a compiler that doesn't support arguments could set it
to 0 to indicate that arguments aren't supported.)

In practice, if there are no arguments, argc will usually be 1.

If argc is 1, your first "if" will fail, and your second
"if" will cause an ILLEGAL MEMORY ACCESS at runtime.

Hence the first "if" should read:

if (argc < 2) {


fprintf(stderr, "parsing usage error\n");
return 1;
}

Insisting that argc be at least 2 is the only way to insure
that referencing "argv[1]" is legal.

--
Cheers,
Robbie Hatley
lonewolf at well dot com
www dot well dot com slant tilde lonewolf slant


James Harris

unread,
Mar 11, 2010, 4:49:10 AM3/11/10
to

An additional point: if you write the above code to print the args
keep it handy as you will be able to use it to find out

- how arguments are delimited
- how argv[0] appears when the command is
- in the path and found implicitly
- explicitly specified
- what happens if you put an argument in quotes
- what happens when you use backslashes before spaces
- what happens when you put backslashes elswehere
- what happens when you use wild cards in arguments
- etc

When run in the appropriate environment it will also show any
differences between the way Unix and Windows handle command line
arguments.

Seeing what's going on is an aid to understanding.

James

Nick Keighley

unread,
Mar 11, 2010, 5:29:00 AM3/11/10
to
On 10 Mar, 22:50, "Bill Cunningham" <nos...@nspam.invalid> wrote:

> Ā  Ā  This simple little program takes from stdin and writes to stdout. No

> other streams are involved. Why am I segmentation faulting? I am guessing [...]

<snip>

why? Why are you guessing? Why don't you debug the program? Use a
debugger or put in printf()s or use assert()s

Bill Cunningham

unread,
Mar 11, 2010, 8:05:53 AM3/11/10
to

"Ike Naar" <i...@localhost.claranet.nl> wrote in message
news:hn9agl$j6p$1...@news.eternal-september.org...

> If argc = 1, argv[0] is a valid string but argv[1] = NULL.
> You wouldn't want to dereference argv[1] in that case.

That's another thing I tried without really understanding what I was
doing and it worked. When I tried argv[1] without the dereference I got an
error somethng like "pointer to int..." something. So I put in the *argv[1]
and it worked. Except for the seg. fault.

Bill


Bill Cunningham

unread,
Mar 11, 2010, 8:09:48 AM3/11/10
to

"Robbie Hatley" <see.my.s...@for.my.contact.info> wrote in message
news:JsydnQQ2VaIeMQXW...@giganews.com...

[snip]

> According to section 5.1.2.2.1 of the C standard:
> - argc must be non-negative
> - argv[argc] must be a null pointer
> - if argc is greater than zero, then argv[0] is NOT an argument,
> it's the name of the program, or an empty string if the program
> name is not available.
> - if argc is greater than one, argv[1] through argv[argc-1]
> will be your program parameters.
>
> In other words, argc is "count of items in argv", NOT "count of
> arguments".

Oh I see.

Bill Cunningham

unread,
Mar 11, 2010, 8:11:01 AM3/11/10
to

"Nick" <3-no...@temporary-address.org.uk> wrote in message
news:87eijr8...@temporary-address.org.uk...

> No it doesn't. It never touches stdin.
>
> It uses the parameters passed in argv, but that's nothing at all to do
> with "taking from stdin".

It takes input from the keyboard. I thought that was stdin.

Bill


Nick

unread,
Mar 11, 2010, 2:14:08 PM3/11/10
to
"Bill Cunningham" <nos...@nspam.invalid> writes:

No, it takes input from the command line.

I can create a shell that launches it with a suitable input string and
make it that this is run whenever I log onto the computer. No keyboard
input in sight.

Andrew Poelstra

unread,
Mar 11, 2010, 2:25:48 PM3/11/10
to
On 2010-03-11, Nick <3-no...@temporary-address.org.uk> wrote:

> "Bill Cunningham" <nos...@nspam.invalid> writes:
>
>>
>> It takes input from the keyboard. I thought that was stdin.
>
> No, it takes input from the command line.
>
> I can create a shell that launches it with a suitable input string and
> make it that this is run whenever I log onto the computer. No keyboard
> input in sight.

To be fair, you can do this with stdin as well.

--
Andrew Poelstra
http://www.wpsoftware.net/andrew

Kenny McCormack

unread,
Mar 11, 2010, 6:39:37 PM3/11/10
to
In article <slrnhpigm1.8...@localhost.localdomain>,

Andrew Poelstra <apoe...@wpsoftware.net> wrote:
>On 2010-03-11, Nick <3-no...@temporary-address.org.uk> wrote:
>> "Bill Cunningham" <nos...@nspam.invalid> writes:
>>
>>>
>>> It takes input from the keyboard. I thought that was stdin.
>>
>> No, it takes input from the command line.
>>
>> I can create a shell that launches it with a suitable input string and
>> make it that this is run whenever I log onto the computer. No keyboard
>> input in sight.
>
>To be fair, you can do this with stdin as well.

How do you know that? Perhaps Nick doesn't know how to do that.

Really, for a group that prides itself on
anal-retentive-to-the-max-don't-claim-anything-as-true-that-isn't-100%-true-in-all-possible-cases-in-all-possible-universes,
the claim made above is really far-fetched.

Ike Naar

unread,
Mar 11, 2010, 7:04:22 PM3/11/10
to
In article <4b98eaaf$0$12416$bbae...@news.suddenlink.net>,

The point is not that you should try argv[1] without the dereference.
You _should_ use *argv[1], (that is, with the dereference), but first
you should check whether it is safe to dereference argv[1], and that is
only the case if argc is at least two; if argc equals zero, argv[1] is
indeterminate and cannot be dereferenced; if argc equals one, argv[1]
is NULL and cannot be dereferenced. If argc is at least two, argv[1]
points to a valid string and can be dereferenced.

In your program, you exit early if argc equals 0. That is good.
If argc is nonzero, you continue, and then dereference argv[1].
But all you know is that argc is nonzero; if argc equals 1 (which
is a nonzero value) you dereference argv[1] anyway, and that is wrong.

So, what you should do is the following:
- check whether argc is at most 1 (equals 0 or equals 1), if so, exit early.
- otherwise, continue, and since argc is now at least 2,
it is safe to dereference argv[1].

Nick

unread,
Mar 12, 2010, 2:54:44 AM3/12/10
to
Andrew Poelstra <apoe...@localhost.localdomain> writes:

> On 2010-03-11, Nick <3-no...@temporary-address.org.uk> wrote:
>> "Bill Cunningham" <nos...@nspam.invalid> writes:
>>
>>>
>>> It takes input from the keyboard. I thought that was stdin.
>>
>> No, it takes input from the command line.
>>
>> I can create a shell that launches it with a suitable input string and
>> make it that this is run whenever I log onto the computer. No keyboard
>> input in sight.
>
> To be fair, you can do this with stdin as well.

True. Nevertheless, using command line arguments is /not/ "taking from
stdin".

Kenny McCormack

unread,
Mar 12, 2010, 5:18:07 AM3/12/10
to
In article <871vfq7...@temporary-address.org.uk>,

Nick <3-no...@temporary-address.org.uk> wrote:
>Andrew Poelstra <apoe...@localhost.localdomain> writes:
>
>> On 2010-03-11, Nick <3-no...@temporary-address.org.uk> wrote:
>>> "Bill Cunningham" <nos...@nspam.invalid> writes:
>>>
>>>>
>>>> It takes input from the keyboard. I thought that was stdin.
>>>
>>> No, it takes input from the command line.
>>>
>>> I can create a shell that launches it with a suitable input string and
>>> make it that this is run whenever I log onto the computer. No keyboard
>>> input in sight.
>>
>> To be fair, you can do this with stdin as well.
>
>True. Nevertheless, using command line arguments is /not/ "taking from
>stdin".

It could be/could have been. What do you suppose the shell reads from
when you are typing a command?

Rui Maciel

unread,
Mar 12, 2010, 10:44:53 AM3/12/10
to
Bill Cunningham wrote:

> I'm not quite understanding here. "Nonzero is not good enough." If there
> are no argc's I want the program to terminate with the "usage error"
> error. As long as it is nonzero I am happy. I'm stuck on this one.

The OS always passes at least one argument, the program's name, which is available through
argv[0]. The following parameters, if any were passed, will be available in argv[1],
argv[2],...

On a side note, if I'm not mistaken it's possible that the OS may pass a NULL instead of a
string containing the program's name. Nonetheless, argv[0] is always reserved for that task
and the remaining parameters will always be passed from argv[1] forward.


Rui Maciel

Rui Maciel

unread,
Mar 12, 2010, 10:40:10 AM3/12/10
to
Bill Cunningham wrote:

> This simple little program takes from stdin and writes to stdout. No
> other streams are involved. Why am I segmentation faulting? I am guessing
> it has something to do with the argc==0 part of the program but I don't
> know how I should change it.
> All characters on each line should begin with an '+' otherwise the
> characters aren't printed or in this case an error is triggered.
>
> Bill#include <stdio.h>
> #include <string.h>
>
> int main(int argc, char *argv[])
> {
> if (argc == 0)

argc is guaranteed to be greater than zero, as argv indicates the number of parameters
which were passed. As argv[0] is used to point to the program's name, it will always be at
least 1. Therefore, this test is always false...


> {
> fprintf(stderr, "parsing usage error\n");
> return 1;
> }

...and the previous code will never run.

As the previous sanity check failed, then in this next LoC, if you haven't passed any
argument to your program then your program will attempt to access memory which isn't
allowed to access. Hence, when you run your compiled program without ever passing any
arguments to it, and therefore will not have any memory reserved to argv[1], you will get a
segmentation faul.


> if (*argv[1] == '+') {
> puts("good + found\n");
> return 0;
> } else {
> if (*argv[1] != '+') {
> fputs("error + not found\n", stderr);
> return 1;
> }
> return 0;
>
> }
> return 0;
> }


Hope this helps,
Rui Maciel

Seebs

unread,
Mar 12, 2010, 12:58:03 PM3/12/10
to
On 2010-03-12, Rui Maciel <rui.m...@gmail.com> wrote:
> argc is guaranteed to be greater than zero, as argv indicates the number of parameters
> which were passed. As argv[0] is used to point to the program's name, it will always be at
> least 1. Therefore, this test is always false...

Not so. It is possible (though unusual) to have argc be zero, and
argv[0] to be null.

It's not COMMON, but there's nothing prohibiting it.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / usenet...@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!

osmium

unread,
Mar 12, 2010, 1:10:26 PM3/12/10
to
Seebs wrote:\

> On 2010-03-12, Rui Maciel <rui.m...@gmail.com> wrote:
>> argc is guaranteed to be greater than zero, as argv indicates the
>> number of parameters which were passed. As argv[0] is used to point
>> to the program's name, it will always be at least 1. Therefore, this
>> test is always false...
>
> Not so. It is possible (though unusual) to have argc be zero, and
> argv[0] to be null.
>
> It's not COMMON, but there's nothing prohibiting it.

Since the word null has several meanings I can't convert your comment into
something that makes sense to me. For those of us who do not get warm
tingly feelings from reading the standard, how about quoting the relevant
parts?

I would think that if argc went to 0, argv would not exist. And the
standard couldn't even mention argv and the contents of the first cell in
that array.


Willem

unread,
Mar 12, 2010, 1:17:24 PM3/12/10
to
osmium wrote:
) Seebs wrote:\
)> Not so. It is possible (though unusual) to have argc be zero, and
)> argv[0] to be null.
)>
)> It's not COMMON, but there's nothing prohibiting it.
)
) Since the word null has several meanings I can't convert your comment into
) something that makes sense to me. For those of us who do not get warm
) tingly feelings from reading the standard, how about quoting the relevant
) parts?
)
) I would think that if argc went to 0, argv would not exist. And the
) standard couldn't even mention argv and the contents of the first cell in
) that array.

AFAIK, argv[argc] == NULL

In other words, argv[] is an array with argc+1 elements,
the last of which is NULL. A NULL-terminated list, iow.

I'm sure somebody will come along with the relevant parts of the standard.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT

Seebs

unread,
Mar 12, 2010, 1:26:41 PM3/12/10
to
On 2010-03-12, osmium <r124c...@comcast.net> wrote:
> Since the word null has several meanings I can't convert your comment into
> something that makes sense to me. For those of us who do not get warm
> tingly feelings from reading the standard, how about quoting the relevant
> parts?

Don't have them to hand. :)

> I would think that if argc went to 0, argv would not exist. And the
> standard couldn't even mention argv and the contents of the first cell in
> that array.

argv HAS to exist. It is a pointer to at least argc+1 pointers, the last of
which is a null pointer.

So if argc is 0, then argv[0] == NULL.

Similarly, if argc is 1, then argv[0] is not null, and argv[1] is null.

Ben Bacarisse

unread,
Mar 12, 2010, 1:36:22 PM3/12/10
to
"osmium" <r124c...@comcast.net> writes:

> Seebs wrote:\
>
>> On 2010-03-12, Rui Maciel <rui.m...@gmail.com> wrote:
>>> argc is guaranteed to be greater than zero, as argv indicates the
>>> number of parameters which were passed. As argv[0] is used to point
>>> to the program's name, it will always be at least 1. Therefore, this
>>> test is always false...
>>
>> Not so. It is possible (though unusual) to have argc be zero, and
>> argv[0] to be null.
>>
>> It's not COMMON, but there's nothing prohibiting it.
>
> Since the word null has several meanings I can't convert your comment into
> something that makes sense to me. For those of us who do not get warm
> tingly feelings from reading the standard, how about quoting the relevant
> parts?

The main bits are:

5.1.2.2.1 Program startup

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

-- The value of argc shall be nonnegative.
-- argv[argc] shall be a null pointer.

Further bullet points explain what must be the case when argc > 0.

> I would think that if argc went to 0, argv would not exist. And the
> standard couldn't even mention argv and the contents of the first cell in
> that array.

argc is not the size of the argv array (technically the array pointed
to by argv). Instead, argc == 0 implies that there is (at least) one
element to the array -- a null pointer.

--
Ben.

osmium

unread,
Mar 12, 2010, 2:22:45 PM3/12/10
to
Ben Bacarisse wrote:

I guess my mistake was making a WAG that c in argc stood for count. Or
something like that. My interest level in the standard has returned to its
normal, very low, level. Thanks guys, all of you.


Lew Pitcher

unread,
Mar 12, 2010, 2:51:46 PM3/12/10
to

At one time, it did. Times have changed, though, and the standardization of
the C language subtly changed the meaning of "argc" to what it is now in
the standard.

FWIW, here's the relevant part of the "original" standard (K&R v1)

5.11 Command-line Arguments

In environments that support C, there is a way to pass command-line
arguments or parameters to a program when it begins executing. When
main is called to begin execution, it is called with two arguments. The
the first (conventionally called argc) is the number of command-line
arguments the program was invoked with; the second (argv) is a pointer to
an array of character strings that contain the arguments, one per string.

("The C Programming Language" by Brian W. Kernighan and Dennis M. Ritchie,
Copyright (c) 1978 by Bell Telephone Laboratories, Incorporated,
Published by Prentice-Hall, Inc., Englewood Cliffs, New Jersey 07632)

> My interest level in the standard has returned to its
> normal, very low, level. Thanks guys, all of you.
>
>

--
Lew Pitcher
Master Codewright & JOAT-in-training | Registered Linux User #112576
Me: http://pitcher.digitalfreehold.ca/ | Just Linux: http://justlinux.ca/
---------- Slackware - Because I know what I'm doing. ------


Ben Bacarisse

unread,
Mar 12, 2010, 3:41:25 PM3/12/10
to
"osmium" <r124c...@comcast.net> writes:

I think the 'c' can still be considered a count. argv is terminated
with a null pointer but I wouldn't expect such a sentinel to be
included in the count. Looked at this way, argc is still a count but
the smallest permissible argv has one (null) element.

<snip>
--
Ben.

pete

unread,
Mar 12, 2010, 11:11:01 PM3/12/10
to
osmium wrote:
>
> Seebs wrote:\

> > It is possible (though unusual) to have argc be zero, and
> > argv[0] to be null.
> >
> > It's not COMMON, but there's nothing prohibiting it.

> For those of us who do not get warm


> tingly feelings from reading the standard,
> how about quoting the relevant parts?

N869
5.1.2.2.1 Program startup

[#2]

-- If the value of argc is greater than zero,

--
pete

Rui Maciel

unread,
Mar 13, 2010, 7:07:24 AM3/13/10
to
Seebs wrote:

> Not so. It is possible (though unusual) to have argc be zero, and
> argv[0] to be null.
>
> It's not COMMON, but there's nothing prohibiting it.

You are right. The argc parameter must be nonnegative, argv[argc] must be a null pointer and
if argc is greater than zero then argv[0] must represent the program's name. So it appears
that the standard accepts two options for the scenario where no parameter is passed to the
program. Those scenarios are:

a) without parameters: argc == 0, argv[0] == NULL
with n parameters: argc == n+1, argv[0] == NULL, argv[argc] == NULL

b) without parameters: argc == 1, argv[0] == <program name>, argv[1] == NULL
with n parameters: argc == n+1, argv[0] == <program name>, argv[arg] == NULL

...with <program name> being either NULL or a string storing the program's name.

In other words, if any parameter is passed to main() then argv[0] is reserved for the
program's name and all parameters must be available from argv[1] forward.

This means the a) scenario is a bit weird. It means that, in the implementations that follow
it, argc may be either 0 or 2 and argv[0] may never point anywhere besides a NULL. This way
of doing things is a bit non-linear. Does anyone know of any platform which works this way?


Rui Maciel

Ben Bacarisse

unread,
Mar 13, 2010, 8:04:59 AM3/13/10
to
Rui Maciel <rui.m...@gmail.com> writes:

> Seebs wrote:
>
>> Not so. It is possible (though unusual) to have argc be zero, and
>> argv[0] to be null.
>>
>> It's not COMMON, but there's nothing prohibiting it.
>
> You are right. The argc parameter must be nonnegative, argv[argc]
> must be a null pointer and if argc is greater than zero then argv[0]
> must represent the program's name. So it appears that the standard
> accepts two options for the scenario where no parameter is passed to
> the program. Those scenarios are:
>
> a) without parameters: argc == 0, argv[0] == NULL with n parameters:
> argc == n+1, argv[0] == NULL, argv[argc] == NULL
>
> b) without parameters: argc == 1, argv[0] == <program name>, argv[1]
> == NULL with n parameters: argc == n+1, argv[0] == <program name>,
> argv[arg] == NULL
>
> ...with <program name> being either NULL or a string storing the
> program's name.

That's not quite right. The standard says:

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

so there is no permission for argv[1] to be NULL when argc == 1.
argv[1] can be an empty string, but that's as bad as it gets. A
previous paragraph includes:

"If the value of argc is greater than zero, the array members
argv[0] through argv[argc-1] inclusive shall contain pointers to
strings, [...]"

so again, there is no permission for any of the argv elements (except
argv[argc]) to be NULL since NULL is not a "pointer to a string".

> In other words, if any parameter is passed to main() then argv[0] is
> reserved for the program's name and all parameters must be available
> from argv[1] forward.
>
> This means the a) scenario is a bit weird. It means that, in the
> implementations that follow it, argc may be either 0 or 2 and argv[0]
> may never point anywhere besides a NULL.

I don't see how you get these two scenarios. argc can be 0, 1, 2
whatever and none of the argv other than argv[argc] can be NULL.
There *is* a special case when argc == 0 because then there is no
further information available, but that's not a different scenario,
just a single degenerate case.

<snip>
--
Ben.

Ersek, Laszlo

unread,
Mar 13, 2010, 1:24:06 PM3/13/10
to
In article <slrnhpl05k.dip...@guild.seebs.net>, Seebs <usenet...@seebs.net> writes:
> On 2010-03-12, Rui Maciel <rui.m...@gmail.com> wrote:
>> argc is guaranteed to be greater than zero, as argv indicates the number of parameters
>> which were passed. As argv[0] is used to point to the program's name, it will always be at
>> least 1. Therefore, this test is always false...
>
> Not so. It is possible (though unusual) to have argc be zero, and
> argv[0] to be null.
>
> It's not COMMON, but there's nothing prohibiting it.

Actually, there is, at least in the SUS, versions 1 to 4. They all
contain the following sentence verbatim for exec() and co.:

"The arguments represented by arg0, ... are pointers to null-terminated
character strings."

lacos

Richard Heathfield

unread,
Mar 14, 2010, 3:46:48 AM3/14/10
to
Dave Hansen wrote:

> On Mar 10, 5:30 pm, "Bill Cunningham" <nos...@nspam.invalid> wrote:
>> "Ike Naar" <i...@localhost.claranet.nl> wrote in message
>>
>> news:hn9895$6f2$2...@news.eternal-september.org...
>>
>>> For the next line to work, argc should be at least 2;
>>> nonzero is not good enough.
>> I'm not quite understanding here. "Nonzero is not good enough." If there
>> are no argc's I want the program to terminate with the "usage error" error.
>> As long as it is nonzero I am happy. I'm stuck on this one.
>>
>
> It's how array indexing works.
>
> If argc is zero, you cannot access any elements of argv.
>
> If argc is 1, you may only access argv[0].
>
> If you want to access argv[1], argc must be at least 2.
>
> Note: argv[0] is often the string that invoked the program itself. I
> don't think you'll ever see argc==0.

He probably won't. Nevertheless, some people /will/ see argc==0.

I am given to understand that Macs didn't support the concept of command
line arguments, and C implementations got around this by setting argc to
0 and argv[0] to NULL.

Perhaps more importantly, it's pretty easy to set argc to 0 through exec
calls, whether deliberately or accidentally.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within

Mark Hobley

unread,
Mar 14, 2010, 6:08:02 AM3/14/10
to
Rui Maciel <rui.m...@gmail.com> wrote:
> This means the a) scenario is a bit weird. It means that, in the
> implementations that follow it, argc may be either 0 or 2 and argv[0] may
> never point anywhere besides a NULL. This way of doing things is a bit
> non-linear. Does anyone know of any platform which works this way?

I'm not sure. I know that MSDOS does not provide the program name in the
command line arguments, but I never looked at how a C compiler handled that.

Mark.

--
Mark Hobley
Linux User: #370818 http://markhobley.yi.org/

Coos Haak

unread,
Mar 14, 2010, 8:16:40 AM3/14/10
to
Op Sun, 14 Mar 2010 10:08:02 GMT schreef Mark Hobley:

> Rui Maciel <rui.m...@gmail.com> wrote:
>> This means the a) scenario is a bit weird. It means that, in the
>> implementations that follow it, argc may be either 0 or 2 and argv[0] may
>> never point anywhere besides a NULL. This way of doing things is a bit
>> non-linear. Does anyone know of any platform which works this way?
>
> I'm not sure. I know that MSDOS does not provide the program name in the
> command line arguments, but I never looked at how a C compiler handled that.
>
> Mark.

MS-DOS puts the path and name of the program after the environment
strings.
TCC returns it in argv[0] as expected.
--
Coos

Rui Maciel

unread,
Mar 14, 2010, 10:31:35 AM3/14/10
to
Ben Bacarisse wrote:

> That's not quite right. The standard says:
>
> "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."
>
> so there is no permission for argv[1] to be NULL when argc == 1.

I don't believe that is true. The standard says in 5.1.2.2.1:

— argv[argc] shall be a null pointer.

So if argc == 1 then argv[1] must be a null pointer.

<snip/>

>> In other words, if any parameter is passed to main() then argv[0] is
>> reserved for the program's name and all parameters must be available
>> from argv[1] forward.
>>
>> This means the a) scenario is a bit weird. It means that, in the
>> implementations that follow it, argc may be either 0 or 2 and argv[0]
>> may never point anywhere besides a NULL.
>
> I don't see how you get these two scenarios. argc can be 0, 1, 2
> whatever and none of the argv other than argv[argc] can be NULL.
> There *is* a special case when argc == 0 because then there is no
> further information available, but that's not a different scenario,
> just a single degenerate case.

Silly me. I've mindlessly read "null character" as being "null pointer". Shameful.


Rui Maciel

Ben Bacarisse

unread,
Mar 14, 2010, 3:23:58 PM3/14/10
to
Rui Maciel <rui.m...@gmail.com> writes:

> Ben Bacarisse wrote:
>
>> That's not quite right. The standard says:
>>
>> "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."
>>
>> so there is no permission for argv[1] to be NULL when argc == 1.
>
> I don't believe that is true. The standard says in 5.1.2.2.1:
>
> — argv[argc] shall be a null pointer.
>
> So if argc == 1 then argv[1] must be a null pointer.

Yes, that was a typo. I was responding to your scenario (a) where you
seemed to suggest that argv[0] could be NULL when argc == 1. I meant
to type: there is no permission for argv[0] to be NULL when argc == 1.

<snip>


>>> In other words, if any parameter is passed to main() then argv[0] is
>>> reserved for the program's name and all parameters must be available
>>> from argv[1] forward.
>>>
>>> This means the a) scenario is a bit weird. It means that, in the
>>> implementations that follow it, argc may be either 0 or 2 and argv[0]
>>> may never point anywhere besides a NULL.
>>
>> I don't see how you get these two scenarios. argc can be 0, 1, 2
>> whatever and none of the argv other than argv[argc] can be NULL.
>> There *is* a special case when argc == 0 because then there is no
>> further information available, but that's not a different scenario,
>> just a single degenerate case.
>
> Silly me. I've mindlessly read "null character" as being "null
> pointer". Shameful.

Ah, well, in that case the whole thing is irrelevant now. If I had
not mistyped it would all have been resolved by now!

--
Ben.

Rui Maciel

unread,
Mar 14, 2010, 8:31:41 PM3/14/10
to
Ben Bacarisse wrote:

<snip/>


>> Silly me. I've mindlessly read "null character" as being "null
>> pointer". Shameful.
>
> Ah, well, in that case the whole thing is irrelevant now. If I had
> not mistyped it would all have been resolved by now!

Damn keyboards. It's a conspiracy, I say.


Rui Maciel

Richard Bos

unread,
Mar 15, 2010, 9:51:50 AM3/15/10
to
Rui Maciel <rui.m...@gmail.com> wrote:

> Bill Cunningham wrote:
>
> > I'm not quite understanding here. "Nonzero is not good enough." If there
> > are no argc's I want the program to terminate with the "usage error"
> > error. As long as it is nonzero I am happy. I'm stuck on this one.
>
> The OS always passes at least one argument, the program's name, which is available through
> argv[0]. The following parameters, if any were passed, will be available in argv[1],
> argv[2],...
>
> On a side note, if I'm not mistaken it's possible that the OS may pass a NULL instead of a
> string containing the program's name.

Not only is this allowable, in such a case argc must be 0 as well.
However, it's also possible for there to be arguments, but argv[0] to
contain an empty string, or some other useless "approximation" of one or
more of the names the program has.

Richard

0 new messages