[comp.unix.wizards] Why isn't argv[argc]==

bengsig@oracle.nl (Bjorn Engsig) (11/16/89)

Sorry if this is discussed often - I don't normally read c.u.w.

The execv family of system calls all have  char *argv[]  as their second
parameter, and you are required to put an endmarker as  (char *)0  in it.
On the other hand, main has  int argc  and  char *argv[]  but here, the
endmarker has disappeared.  Has it ever been considered to change the defi-
nition of main such that it will always be true that  argv[argc] == (char *)0
or to change the execv's to use argc and not an endmarker.

Is it due to the fact that main() is a C-thing whereas exec() is a Unix thing,
and they therefore are incompatible?  If this is the case, why isn't there a
system() counterpart in the scope of C with the same parameters as main()?

It is probably much too late to change anything, but I would just like to 
know if this has ever been considered.
-- 
Bjorn Engsig,	Domain:		bengsig@oracle.nl,
		Path:		uunet!mcsun!orcenl!bengsig
		USA Domain:	bengsig@nlsun1.oracle.com

gwyn@smoke.BRL.MIL (Doug Gwyn) (11/16/89)

In article <547.nlhp3@oracle.nl> bengsig@oracle.nl (Bjorn Engsig) writes:
>The execv family of system calls all have  char *argv[]  as their second
>parameter, and you are required to put an endmarker as  (char *)0  in it.
>On the other hand, main has  int argc  and  char *argv[]  but here, the
>endmarker has disappeared.  Has it ever been considered to change the defi-
>nition of main such that it will always be true that  argv[argc] == (char *)0
>or to change the execv's to use argc and not an endmarker.

What makes you think that argv[argc]!=(char*)0 ?
argv[argc]==(char*)0 is existing practice and is also required by
the C Standard (for hosted implementations, which are the only ones
for which argv is an issue).

There would be no point in changing execv(), especially since it
would break all existing code that used execv().

>Is it due to the fact that main() is a C-thing whereas exec() is a Unix thing,
>and they therefore are incompatible?  If this is the case, why isn't there a
>system() counterpart in the scope of C with the same parameters as main()?

execv() definitely is UNIX- (or POSIX-) specific, but the main()
and execv() interfaces are compatible in this regard since both
originated within the same software development culture.

The C Standard does specify the system() standard library function,
but it just takes a single command string argument, because there
is too wide a variety of execution environments to be more specific.

>It is probably much too late to change anything, but I would just like to 
>know if this has ever been considered.

I don't see the problem.

klee@chico.pa.dec.com (Ken Lee) (11/16/89)

In article <547.nlhp3@oracle.nl>, bengsig@oracle.nl (Bjorn Engsig) writes:
=> The execv family of system calls all have  char *argv[]  as their second
=> parameter, and you are required to put an endmarker as  (char *)0  in it.
=> On the other hand, main has  int argc  and  char *argv[]  but here, the
=> endmarker has disappeared. 

Most (all?) UNIXes have argv[argc]==0, though many, especially System V
based ones, don't document it.  Note that p.115 of the new K&R says
"the [ANSI C] standard requires that argv[argc] be a null pointer".

Ken Lee
DEC Western Software Laboratory, Palo Alto, Calif.
Internet: klee@decwrl.dec.com
uucp: uunet!decwrl!klee

cpcahil@virtech.uucp (Conor P. Cahill) (11/16/89)

In article <547.nlhp3@oracle.nl>, bengsig@oracle.nl (Bjorn Engsig) writes:
> The execv family of system calls all have  char *argv[]  as their second
> parameter, and you are required to put an endmarker as  (char *)0  in it.
> On the other hand, main has  int argc  and  char *argv[]  but here, the
> endmarker has disappeared.  Has it ever been considered to change the defi-

argv has always had an endmarker.  Older versions had the convention 
that argv[argc] == -1.  Currently under System V argv[argc] = (char *) 0.



-- 
+-----------------------------------------------------------------------+
| Conor P. Cahill     uunet!virtech!cpcahil      	703-430-9247	!
| Virtual Technologies Inc.,    P. O. Box 876,   Sterling, VA 22170     |
+-----------------------------------------------------------------------+

bengsig@oracle.nl (Bjorn Engsig) (11/16/89)

In article <547.nlhp3@oracle.nl> I asked the question above.

Sorry, I should have RTFM.  The answer is that they are equal in ANSI C.
-- 
Bjorn Engsig,	Domain:		bengsig@oracle.nl,
		Path:		uunet!mcsun!orcenl!bengsig
		USA Domain:	bengsig@nlsun1.oracle.com

meissner@dg-rtp.dg.com (Michael Meissner) (11/17/89)

In article <547.nlhp3@oracle.nl> bengsig@oracle.nl (Bjorn Engsig) writes:

|  The execv family of system calls all have  char *argv[]  as their second
|  parameter, and you are required to put an endmarker as  (char *)0  in it.
|  On the other hand, main has  int argc  and  char *argv[]  but here, the
|  endmarker has disappeared.  Has it ever been considered to change the defi-
|  nition of main such that it will always be true that  argv[argc] == (char *)0
|  or to change the execv's to use argc and not an endmarker.
|  
|  Is it due to the fact that main() is a C-thing whereas exec() is a Unix thing,
|  and they therefore are incompatible?  If this is the case, why isn't there a
|  system() counterpart in the scope of C with the same parameters as main()?
|  
|  It is probably much too late to change anything, but I would just like to 
|  know if this has ever been considered.

I don't know what version of the standard you are reading, but in the
draft dated December 7, 1988, it states in section 2.1.2.2 on page 8:

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

* The value of argc shall be nonegative.

* argv[argc] shall be a null pointer.

...

Note, this effectively rules out a ANSI C implementation on a Version
6 system (V6 for whatever reason, put -1 in argv[argc], and had a note
in the exec* man pages that you couldn't pass argv to execve).  I
seriously doubt anybody is worried about this....

--

Michael Meissner, Data General.				If compiles where much
Uucp:		...!mcnc!rti!xyzzy!meissner		faster, when would we
Internet:	meissner@dg-rtp.DG.COM			have time for netnews?

gwyn@smoke.BRL.MIL (Doug Gwyn) (11/18/89)

In article <MEISSNER.89Nov17094904@tiktok.rtp.dg.com> meissner@dg-rtp.dg.com (Michael Meissner) writes:
>Note, this effectively rules out a ANSI C implementation on a Version
>6 system (V6 for whatever reason, put -1 in argv[argc], ...

Actually that can easily be fixed by the start-up module.
I did that once, long ago.

ckl@uwbln.UUCP (Christoph Kuenkel) (11/18/89)

In article <11606@smoke.BRL.MIL>, gwyn@smoke.BRL.MIL (Doug Gwyn) writes:
> What makes you think that argv[argc]!=(char*)0 ?
> argv[argc]==(char*)0 is existing practice and is also required by
> [...]
> execv() definitely is UNIX- (or POSIX-) specific, but the main()
> and execv() interfaces are compatible in this regard since both
> originated within the same software development culture.
well, main() and execv() originate in the first versions of UNIX and
at least in Version 6, argv[argc] was (char *) -1.  The manual page stated
that argv could not be used directly in a call to execv().  in version 7,
they purged the ``not'' from the manual page....

i'm not sure but maybe the v6 style behaviour survived in some unix derivates?

christoph
-- 
# include <std/disclaimer.h>
Christoph Kuenkel/UniWare GmbH       Kantstr. 152, 1000 Berlin 12, West Germany
ck@tub.BITNET                ckl@uwbln             {unido,tmpmbx,tub}!uwbln!ckl

dcm@toysrus.uucp (dcm) (11/21/89)

Well, just to throw in my $.02, K&R #2 states "additionally, the standard
requires that argv[argc] be a null pointer." (p 115)

But, both the 1st and 2nd editions take great care in using argc to
walk thru argv, not argv[argc] != NULL.  I don't think they *ever* do
a (while *argv != NULL)...

Argc should always be correct.  Who cares about argv[argc]?

I remember a VMS system some years ago where argv[0] was "main" or
something idiotic like that.  Err.

	Craig Miller
	..!cs.utexas.edu!ibmaus!auschs!toysrus.austin.ibm.com!dcm
--------
	Craig Miller
	contractor @ IBM Austin
	UUCP: ..!cs.utexas.edu!ibmaus!auschs!toysrus.austin.ibm.com!dcm
	"I don't believe in .signatures."

guy@auspex.auspex.com (Guy Harris) (11/21/89)

>argv has always had an endmarker.  Older versions had the convention 
>that argv[argc] == -1.

*Much* older versions; the first version I saw with argv[argc] == 0 was
V7, from which all modern AT&T-UNIX-derived versions are derived. 
(I.e., unless you have to deal with an archaic UNIX or a Mutant UNIX
From Hell, you can count on argv[argc] == 0.)

klee@chico.pa.dec.com (Ken Lee) (11/21/89)

In article <3053@cello.UUCP>, dcm@toysrus.uucp (dcm) writes:
> Argc should always be correct.  Who cares about argv[argc]?

The problem is that some UNIX functions, such as execv, do not take an
argc.  If your system does not force argv[argc]==NULL, you cannot
directly pass your argv (or the last part of it) to execv.

Ken Lee
DEC Western Software Laboratory, Palo Alto, Calif.
Internet: klee@decwrl.dec.com
uucp: uunet!decwrl!klee

richard@aiai.ed.ac.uk (Richard Tobin) (11/22/89)

In article <2651@auspex.auspex.com> guy@auspex.auspex.com (Guy Harris) writes:

>*Much* older versions; the first version I saw with argv[argc] == 0 was V7

So it's probably the first version that had it.  From the Sixth Edition
man page for exec(II):

 "Argv is not directly usable in another execv, since argv[argc] is -1
  and not 0."

-- Richard
-- 
Richard Tobin,                       JANET: R.Tobin@uk.ac.ed             
AI Applications Institute,           ARPA:  R.Tobin%uk.ac.ed@nsfnet-relay.ac.uk
Edinburgh University.                UUCP:  ...!ukc!ed.ac.uk!R.Tobin

pim@cti-software.nl (Pim Zandbergen) (11/23/89)

guy@auspex.auspex.com (Guy Harris) writes:

>(I.e., unless you have to deal with an archaic UNIX or a Mutant UNIX
>From Hell, you can count on argv[argc] == 0.)

In X/OS, a SYSV/BSD hybrid operating system for the Olivetti LSX
minicomputers, a reference to argv[argc] will make your program dump core.

-- 
Pim Zandbergen                                   domain : pim@cti-software.nl
CTI Software BV                                  uucp   : ..!uunet!ctisbv!pim
Laan Copes van Cattenburch 70                    phone  : +31 70 542302
2585 GD The Hague, The Netherlands               fax    : +31 70 512837

ckl@uwbln.UUCP (Christoph Kuenkel) (11/23/89)

In article <1635@ctisbv.cti-software.nl>, pim@cti-software.nl (Pim Zandbergen) writes:
> guy@auspex.auspex.com (Guy Harris) writes:
> >(I.e., unless you have to deal with an archaic UNIX or a Mutant UNIX
> >From Hell, you can count on argv[argc] == 0.)
> 
> In X/OS, a SYSV/BSD hybrid operating system for the Olivetti LSX
> minicomputers, a reference to argv[argc] will make your program dump core.
which is SVID conformant.  as mentioned before, the SVID does not say 
anything about argv[argc] but states that

	"argc is the argument count, argv is an array of character pointers
	 to the argument themselves"

thus *(argv[argc]) may legally dump core.
-- 
# include <std/disclaimer.h>
Christoph Kuenkel/UniWare GmbH       Kantstr. 152, 1000 Berlin 12, West Germany
ck@tub.BITNET                ckl@uwbln             {unido,tmpmbx,tub}!uwbln!ckl

gwyn@smoke.BRL.MIL (Doug Gwyn) (11/24/89)

In article <1391@skye.ed.ac.uk> richard@aiai.UUCP (Richard Tobin) writes:
>So it's probably the first version that had it.  From the Sixth Edition
>man page for exec(II):

C as delivered with Sixth Edition UNIX is unusable anyway by today's
standards.  Long, long ago I upgraded the C system on the Sixth Edition
UNIX installation that I was responsible for, and many others did the
same.  One of the things that we fixed was the use everywhere of -1 as
an "invalid pointer" indicator; that is untenable in modern C.

(Yes, I know about sbrk() and SIG_ERR.)

martin@mwtech.UUCP (Martin Weitzel) (11/24/89)

In article <1989@uwbull.uwbln.UUCP> ckl@uwbln.UUCP (Christoph Kuenkel) writes:
[some lines deleted]
>which is SVID conformant.  as mentioned before, the SVID does not say 
>anything about argv[argc] but states that
>
>	"argc is the argument count, argv is an array of character pointers
>	 to the argument themselves"

My personal opinion is, that the SVID just did forget to mention.
I conclude this from
 a) SVID has several weak points (some errors also)
 b) On the pages you quote from, I also found nothing about
    how "envp" is terminated.
"envp" is by convention (char *)0 too, and I think this is true on
*all* systems, because how would you know otherwise, when to terminate
stepping thru "envp"? There is no such thing as "envc"! You may argue,
that it is not intended stepping thru "envp" rather use "getenv()" and
that this function may have a secret way to determine when to stop.
But then, why mention "envp" as formal parameter of "main" at all?

Last and final: From the very beginning SVID stated, they will strongly
consider full conformance to X3J11 - and X3J11 has no doubt about that
argv[argc] is a null pointer.

MW

guy@auspex.auspex.com (Guy Harris) (11/25/89)

>well, main() and execv() originate in the first versions of UNIX and
>at least in Version 6, argv[argc] was (char *) -1.  The manual page stated
>that argv could not be used directly in a call to execv().  in version 7,
>they purged the ``not'' from the manual page....

...because they purged that "terminate it with -1" behavior from the
system.

>i'm not sure but maybe the v6 style behaviour survived in some unix derivates?

Not in V7, and not in its derivatives BSD and System {III,V}.  If you
know of any derivatives in which it still survives, let us know so we
can avoid those Mutant UNIXes From Hell....

guy@auspex.auspex.com (Guy Harris) (11/28/89)

>>(I.e., unless you have to deal with an archaic UNIX or a Mutant UNIX
>>From Hell, you can count on argv[argc] == 0.)
>
>In X/OS, a SYSV/BSD hybrid operating system for the Olivetti LSX
>minicomputers, a reference to argv[argc] will make your program dump core.

If you mean "a *de*reference *of* 'argv[argc]' will make your program
dump core", that's true on Suns as well, and some other machines, since
they don't let you dereference null pointers.

If you mean "even trying to copy the (pointer) *value* somewhere else
causes a core dump", then I think the label "Mutant UNIX From Hell" is
well-deserved; I've nothing against, say, array bounds-checking, but
"argv" has "argc+1" elements, not "argc" elements - if Olivetti intends
to get POSIX or ANSI C support on the LSX, they'd better fix this....

ckl@uwbln.UUCP (Christoph Kuenkel) (11/29/89)

In article <497@mwtech.UUCP>, martin@mwtech.UUCP (Martin Weitzel) writes:
> My personal opinion is, that the SVID just did forget to mention.
> [...]
I agree totally although i wonder why they purged the sentence in
question which was present in the old manual pages.  The problem is,
that some implementors will read the specs and implement what is
written there.  You as a software developer will have a hard time
argueing ``well, but look, your implementation doesnt make sense'' when
your program dumps core and the words are against you :-(

> Last and final: From the very beginning SVID stated, they will strongly
> consider full conformance to X3J11 - and X3J11 has no doubt about that
> argv[argc] is a null pointer.
You should send a gripe to at&t :-)
I dont have my XPG3 at hand, but i bet its the same wording there!

christoph
-- 
# include <std/disclaimer.h>
Christoph Kuenkel/UniWare GmbH       Kantstr. 152, 1000 Berlin 12, West Germany
ck@tub.BITNET                ckl@uwbln             {unido,tmpmbx,tub}!uwbln!ckl

mje@olsa99.UUCP (Mark J Elkins) (12/15/89)

In article <2673@auspex.auspex.com>, guy@auspex.auspex.com (Guy Harris) writes:
Guy >>>(I.e., unless you have to deal with an archaic UNIX or a Mutant UNIX
Guy >>>From Hell, you can count on argv[argc] == 0.)

In article <1635@ctisbv.cti-software.nl> Pim Zandgerger wrote...
Pim >>In X/OS, a SYSV/BSD hybrid operating system for the Olivetti LSX
Pim >>minicomputers, a reference to argv[argc] will make your program dump core.

> If you mean "a *de*reference *of* 'argv[argc]' will make your program
> dump core", that's true on Suns as well, and some other machines, since
> they don't let you dereference null pointers.
> 
> If you mean "even trying to copy the (pointer) *value* somewhere else
> causes a core dump", then I think the label "Mutant UNIX From Hell" is
> well-deserved; I've nothing against, say, array bounds-checking, but
> "argv" has "argc+1" elements, not "argc" elements - if Olivetti intends
> to get POSIX or ANSI C support on the LSX, they'd better fix this....

Mark Elkins writes....

OK Guys - I am the support person for Olivetti Africa and was a little
upset about the accusation. I ran the following program... (Called 'e.c')


main(ac,av)
int ac;
char *av[];
{
char *cp;

printf("Value of av[ac] = %s\n",av[ac]);
cp = av[ac]; printf("Value of cp = %s\n",cp);
while (ac >= 0) printf("Arg %d = %s\n",ac--,*av++);
}

and it produced.....


Value of av[ac] = (null)
Value of cp = (null)
Arg 4 = e
Arg 3 = one
Arg 2 = two
Arg 1 = three
Arg 0 = (null)

The Machine is a LSX 3020 Machine (68020 @ 17 Meg) running X/OS Rel 2.1
(Olivetti's Unix - Bastardisation of Sys V Rel 3.0 and BSD 4.2 - peppered
with Olivetti features)

Go suck eggs  (or maybe upgrade your system)

(Any replies - please mail mje@olsa99 - my news feed is down)
-- 
  .  .     ___. .__       Olivetti Africa, Unix 'Everything-except-sales'
 /| /|       / /__        UUCP: uunet!olsa99!mje (Mark J Elkins)
/ |/ |ARK \_/ /__ LKINS   mje@olsa99.UUCP   - Living in GMT-2

guy@auspex.UUCP (Guy Harris) (12/19/89)

>OK Guys - I am the support person for Olivetti Africa and was a little
>upset about the accusation.

You mean the accusation that

>Pim >>In X/OS, a SYSV/BSD hybrid operating system for the Olivetti LSX
>Pim >>minicomputers, a reference to argv[argc] will make your program
>Pim >>dump core.

?  Said accusation was either incorrect or poorly stated; as indicated
in my article, it could either mean "a dereference of 'argv[argc]'" will
make your program drop core" (not proved true or false by your example
program - see below - and if it's true, that's perfectly legitimate) or
"even trying to use the pointer value 'argv[argc]' will cause your
program to drop core" (proven false by your example, which is fortunate,
since if it *were* true, it *would* have been a Mutant UNIX From Hell).

>printf("Value of av[ac] = %s\n",av[ac]);

"printf" implementations often check for null pointer values passed to
"%s", and print "(null)" when a null pointer is used; if you want to see
whether dereferencing a null pointer on your machine causes a core dump
(if it does, 10,000 cheers for Olivetti; disallowing dereferencing of
null pointers will catch annoying bugs), do:

	#include <stdio.h>

	int
	main(av, ac)
		int av;
		char **ac;
	{
		if (av[ac][0] == 'z')
			(void) printf("Oh well, it lets me dereference null\n");
		return 0;
	}