[comp.lang.c] argv[] terminated by a NULL pointer?

angst@cs.ucsb.edu (Hopelessly in love w/Donna Reed) (06/23/91)

[I looked in the FAQ and this wasn't mentioned.]

I'm porting some code that assumes that the argv[] array is terminated
by a NULL pointer, rather than just using argc to determine the number
of arguments passed to the program.

I was always taught to use argc, and was of the belief that argv[] is
not necessarily terminated by a NULL pointer.

The only reason I can come up with for people thinking that it is
terminated with a NULL pointer is the calling syntax for the the 
different forms of exec, which require the argument array to be
terminated by a NULL.

So I guess my question is: am I right in my belief that argv[] 
is not *guaranteed* to be terminated by a NULL pointer?  

Thanks.

"Let the fools have their tartar sauce."	|          Dave Stein
  		        - Mr. Burns		|       angst@cs.ucsb.edu
						|    angst%cs@ucsbuxa.bitnet

wirzeniu@klaava.Helsinki.FI (Lars Wirzenius) (06/23/91)

In article <12187@hub.ucsb.edu> angst@cs.ucsb.edu (Hopelessly in love w/Donna Reed) writes:
>So I guess my question is: am I right in my belief that argv[] 
>is not *guaranteed* to be terminated by a NULL pointer?  

The first edition of K&R doesn't say anything (as far as I can see)
about argv being terminated with NULL, so I think you're right. A quick
check with VMS C gives an access violation, cc and gcc on SunOS do have
a terminating NULL, however.

Also, the ANSI standard guarantees that argv[argc] == NULL.
-- 
Lars Wirzenius     wirzeniu@cc.helsinki.fi

torek@elf.ee.lbl.gov (Chris Torek) (06/24/91)

In article <12187@hub.ucsb.edu> angst@cs.ucsb.edu
(Hopelessly in love w/Donna Reed) writes:
>I'm porting some code that assumes that the argv[] array is terminated
>by a NULL pointer....  am I right in my belief that argv[] is not
>*guaranteed* to be terminated by a NULL pointer?  

Under Version 6 Unix, argv[argc] is (char *)-1.  This violates the
following wording from X3.159-1989 (`ANSI C'):

    argv[argc] shall be a null pointer.  (2.1.1.2, p. 7)

Thus, the answer to your question is both `no' and `yes'.
-- 
In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 415 486 5427)
Berkeley, CA		Domain:	torek@ee.lbl.gov

bhoughto@pima.intel.com (Blair P. Houghton) (06/24/91)

In article <14603@dog.ee.lbl.gov> torek@elf.ee.lbl.gov (Chris Torek) writes:
>Under Version 6 Unix, argv[argc] is (char *)-1.  This violates the
>following wording from X3.159-1989 (`ANSI C'):
>    argv[argc] shall be a null pointer.  (2.1.1.2, p. 7)
>Thus, the answer to your question is both `no' and `yes'.

Unless, of course, `(char *)-1' compares equal to a null pointer...

				--Blair
				  "Yeah, I know, just go back
				   into my corner and keep typing..."

henry@zoo.toronto.edu (Henry Spencer) (06/26/91)

In article <12187@hub.ucsb.edu> angst@cs.ucsb.edu (Hopelessly in love w/Donna Reed) writes:
>I was always taught to use argc, and was of the belief that argv[] is
>not necessarily terminated by a NULL pointer.

Certain immensely ancient Unixes terminated it with a different magic cookie.
This is probably the origin of any weasel-wording on the subject.  All modern
systems written by sensible people :-) have the NULL, and ANSI C demands it.
-- 
"We're thinking about upgrading from    | Henry Spencer @ U of Toronto Zoology
SunOS 4.1.1 to SunOS 3.5."              |  henry@zoo.toronto.edu  utzoo!henry

djimenez@ringer.cs.utsa.edu (Daniel Jimenez) (06/28/91)

In article <14603@dog.ee.lbl.gov> torek@elf.ee.lbl.gov (Chris Torek) writes:
>In article <12187@hub.ucsb.edu> angst@cs.ucsb.edu
>(Hopelessly in love w/Donna Reed) writes:
>>I'm porting some code that assumes that the argv[] array is terminated
>>by a NULL pointer....  am I right in my belief that argv[] is not
>>*guaranteed* to be terminated by a NULL pointer?  
>
>Under Version 6 Unix, argv[argc] is (char *)-1.  This violates the
>following wording from X3.159-1989 (`ANSI C'):
>
>    argv[argc] shall be a null pointer.  (2.1.1.2, p. 7)
>

Who said the null pointer couldn't be -1?
On a system where the null pointer is represented by all bits one,
the following statement:
((char *)0) == ((char *)-1) 
would be true, since 0 in a pointer context is defined to be
the null pointer, and -1 is also the null pointer.
They would have the same bit pattern.
-- 
*    Daniel A. Jimenez			*  Please excuse my longwindedness.
*    djimenez@ringer.cs.utsa.edu	*  This Sun terminal makes everything
*    dajim@lonestar.utsa.edu		*  I write seem important.
* Opinions expressed here are mine only, and not those of UTSA.

greywolf@unisoft.UUCP (The Grey Wolf) (06/28/91)

In article <14603@dog.ee.lbl.gov>, torek@elf.ee.lbl.com (Chris Torek) wrote:
 * In article <12187@hub.ucsb.edu> angst@cs.ucsb.edu
 * [argv terminated by null?]
 *
 * Under Version 6 Unix, argv[argc] is (char *)-1.  This violates the
 * following wording from X3.159-1989 (`ANSI C'):
 * 
 *     argv[argc] shall be a null pointer.  (2.1.1.2, p. 7)
 * 
 * Thus, the answer to your question is both `no' and `yes'.

"Never go to the Elves for counsel,
 for they will tell you both yes and no..."  -- J.R.R. Tolkien

You're sure holding true to form, Chris :-) ...

Anyone got any clues why they started using NULL pointers instead of
(char *) -1?  Is there any system which will actually consider (char *) -1
a valid (virtual) memory location?  Or, rather, WERE there any machines
which would do so (were: most machines now are word-aligned).

 * -- 
 * In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 415 486 5427)
 * Berkeley, CA		Domain:	torek@ee.lbl.gov


-- 
# "Religion is a weapon invented by the sheep to keep the wolves in line."
# greywolf@unisoft.com

torek@elf.ee.lbl.gov (Chris Torek) (06/28/91)

In article <14603@dog.ee.lbl.gov> I noted that
>>Under Version 6 Unix, argv[argc] is (char *)-1.  This violates the
>>following wording from X3.159-1989 (`ANSI C'):
>>    argv[argc] shall be a null pointer.  (2.1.1.2, p. 7)

In article <1991Jun28.052339.14611@ringer.cs.utsa.edu>
djimenez@ringer.cs.utsa.edu (Daniel Jimenez) writes:
>Who said the null pointer couldn't be -1?

Perhaps I was overly terse.  I said `Version 6 Unix'; this implies a
whole range of things, for instance, that sizeof(int)==2, that the type
`long' existed only if you installed the `Phototypesetter V6' C
compiler, and so forth.  One of the implications is that the
implementation's nil-pointer-to-char is 16 zero bits.

>On a system where the null pointer is represented by all bits one,
>the following statement:
>((char *)0) == ((char *)-1) 
>would be true, since 0 in a pointer context is defined to be
>the null pointer, and -1 is also the null pointer.
>They would have the same bit pattern.

Correct, and good to know, but irrelevant to my point.  Once more,
that is:

	argv[argc] will be NULL if you have an ANSI conformant
	compiler.  If not, there is at most a `good chance' that
	it will exist and be NULL.

(Brownie points [Elven points?] to those who caught on to the `no and
yes' bit :-) .  If you look closely, you will find this in many of my
answers: qualifiers and limitations.  Strong, terse Anglo-Saxon verbs
are great, but sentences like `GCC kicks butt!' tend not to match well
to technical situations, and one winds up with polysyllabic provisional
Latinate words and passive voice: `GCC performs moderately well in
terms of generated code, and has the required support to use special
machine instructions needed to implement certain kernel functions.' But
this is heading towards misc.writing territory.  More appropriate here
is Gildor's reply. Frodo: `Go not to the Elves for counsel, for they
will say both no and yes'. Gildor: `Elves seldom give unguarded advice,
for advice is a dangerous gift, even from the wise to the wise.  You
have not told me all concerning yourself, and how then shall I choose
better than you?'  [And yes, I have elided some of the exchange.  That,
too, was intentional.])
-- 
In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 415 486 5427)
Berkeley, CA		Domain:	torek@ee.lbl.gov

dbrooks@osf.org (David Brooks) (06/28/91)

djimenez@ringer.cs.utsa.edu (Daniel Jimenez) writes:
|> Who said the null pointer couldn't be -1?

Who's allowed to know?

|> On a system where the null pointer is represented by all bits one,
|> the following statement:
|> ((char *)0) == ((char *)-1) 
|> would be true, since 0 in a pointer context is defined to be
|> the null pointer, and -1 is also the null pointer.
|> They would have the same bit pattern.

Is this strictly true?  I know that the conversion of an *object* of
integral type is allowed to go through an implementation-dependent mapping,
although K&RII (at least) doesn't seem to mention an integer constant.

It would be rather perverse to map (char *)-1 to 0x8129ac60, but I could
imagine a compiler writer wanting to avoid mapping -1 to a value internally
identical to a null pointer.
-- 
David Brooks				dbrooks@osf.org
Systems Engineering, OSF		uunet!osf.org!dbrooks
Composing for a percussion ensemble is like writing an essay in highlighter.

henry@zoo.toronto.edu (Henry Spencer) (06/29/91)

In article <23292@paperboy.OSF.ORG> dbrooks@osf.org (David Brooks) writes:
>|> On a system where the null pointer is represented by all bits one,
>|> the following statement:
>|> ((char *)0) == ((char *)-1) 
>|> would be true...
>
>Is this strictly true? 

No.  There is a *good chance* that the expression would evaluate to 1,
but no certainty.  The conversion of 0 to `char *' is required to yield
a null pointer.  What happens when you convert -1 to `char *' is
completely up to the implementation.  Remember that -1 is not necessarily
all-bits-one.  Even if it were, the conversion to pointer could legally
change it to something else.

(How might these things happen?  Well, on a one's-complement machine -1
is *not* all-bits-one.  Yes, there are ANSI C compilers on such machines.
As for the conversion to pointer, what happens if a pointer is longer
than an int?  Precisely where the int value gets put in the pointer
value, and how the other bits are filled in, is not defined by the
standard.  In practice, it would depend on what was most convenient
on that particular architecture, and putting the int in the low bits
and doing a sign extension is not the only possibility.)
-- 
Lightweight protocols?  TCP/IP *is*     | Henry Spencer @ U of Toronto Zoology
lightweight already; just look at OSI.  |  henry@zoo.toronto.edu  utzoo!henry