[net.lang.c] Must a NULL pointer be a 0 bit patte

jim@ism780b.UUCP (10/18/84)

It seems to me that K&R guarantees that globals are initialized to zero,
not to a nil pointer.  A lot of code will bite the dust given a machine
with a non-zero nil pointer.

-- Jim Balter, INTERACTIVE Systems (ima!jim)

ron@brl-tgr.ARPA (Ron Natalie <ron>) (10/22/84)

> It seems to me that K&R guarantees that globals are initialized to zero,
> not to a nil pointer.  A lot of code will bite the dust given a machine
> with a non-zero nil pointer.
> 
> -- Jim Balter, INTERACTIVE Systems (ima!jim)

BUT that still doesn't make it legal to 0-> something.

-Ron

mwm@ea.UUCP (10/28/84)

/***** ea:net.lang.c / utzoo!henry / 11:22 am  Oct 23, 1984 */
As I understand it, nobody is claiming that the "first element" rule is
good; all they are claiming is that it's simple and does not have adverse
consequences elsewhere.  Apparently the various alternatives all have
serious problems of one kind or another.
-- 
				Henry Spencer @ U of Toronto Zoology
				{allegra,ihnp4,linus,decvax}!utzoo!henry
/* ---------- */

Was one of the alternatives something similar to the ALGOLW "record constant"
facility? In C, this would translate to:

	(struct gezornin) {"a", 10, 2.3, 'x'}

being considered a constant. Thus, you can do union initialization as so:

	struct gort {
		int	type ;
		union	info {
				struct	gfloat	{ float	gfx, gfy } ;
				struct	gint	{ long	gix, giy } ;
				string	*name ;
				} ;
		} sample[] = {
			{T_FLOAT, (struct glfoat) { 3.4, 5.7 } } ,
			{T_INT, (struct gint) { 243, 56 } } ,
			{T_STRING, (char *) "this is a test" }
			} ;

In other words, add a facility to allow structure constants (useful in *lots*
of places), and then require all union initializations to have an explicit
cast.

The union initializations won't break any existing code (nobody has them
now, right? :-), and the "struct constants" shouldn't break any code.

Comments?

	<mike

jim@ISM780B.UUCP (11/03/84)

>/* Written 12:37 pm  Oct 22, 1984 by ron@brl-tgr in ISM780B:net.lang.c */
>> It seems to me that K&R guarantees that globals are initialized to zero,
>> not to a nil pointer.  A lot of code will bite the dust given a machine
>> with a non-zero nil pointer.
>>
>> -- Jim Balter, INTERACTIVE Systems (ima!jim)
>
>BUT that still doesn't make it legal to 0-> something.
>
>-Ron

I just love those non-sequiturs.  In case you hadn't noticed, *this*
discussion is about whether NULL can be non-zero.

Aside from the case of BSS initialization, which one could argue is equivalent
to an assignment so the compiler can handle pointers by initializing them
(good luck to people who depend on these variables really going into .bss),
there is calloc and memset(&structure, '\0', sizeof structure); these
would have to be changed to explicit member-by-member assignment,
or assignment from a dummy previously initialized structure.
Of course, the standards committee could always get carried away and add
initializers as valid structure constants, like many *modern* languages.

-- Jim Balter, INTERACTIVE Systems (ima!jim)

jim@ISM780B.UUCP (11/03/84)

>As I understand it, nobody is claiming that the "first element" rule is
>good; all they are claiming is that it's simple and does not have adverse
>consequences elsewhere.  Apparently the various alternatives all have
>serious problems of one kind or another.

What is wrong with

	union foo thing.member = {...};

?  It is clear and unambiguous.

-- Jim Balter, INTERACTIVE Systems (ima!jim)

jim@ISM780B.UUCP (11/03/84)

>Three comments about non-zero NULL:
>
>1. Because of implicit comparison with zero, as in "while(p)s;", this idea
>is cannot be implemented simply by changing stdio.h to read
>#define NULL ((char*)0x87654321)

I think you have misunderstood.  There is no intention to change the
definition of NULL.  The changes are in the compiler, to interpret the
constant "0" as different from all zero bits.  Thus,

	register char *p = 0;

would compile into

	l   regp,=x'87654321'

Under no circumstances does "while(p)" have semantics different from
"while(p != 0)" in C.


>2. In making changes to the compiler, this must remain zero:
>        (p = NULL , (int)p)

The language spec does not guarantee it.  In fact, it explicitly considers
the result of this expression to be implementation-dependent.

>Also, for every declared "var", this must remain one:
>        (p = &var , (int)p != 0)

Ditto.  In fact, regardless of the handling of NULL pointers, this expression
may yield zero on machines with ints smaller than pointers, if the low-order
bits of &var are zero.  All of this has been discussed here before.

>3. The issue of how a union can be set to zero was handled properly by the
>correspondent who said the first member is initialized to zero.

Statements like "so and so is right" or "I am for X" without analysis and
argument are rather arrogant.  If you think it is right say why, and
refute other positions (such as that it may be desirable to initialize
different members of different instances of the same union).
I have yet to see an argument *for* always initializing the first member,
other than "all the other methods have problems".  Enumerate the other
methods; state their problems.

I suggest that if an initializer of a union has no explicit cast, it be
converted to the type of the first member, otherwise it has an explicit
content which should become the content of the union, provided it is
type-compatible with at least one member of the union.  The default case
guarantees that this is at least as powerful as "initialize first member".
It is unambiguous, it is complete if it is recognized that (char *)"abc" and
(char [])"abc" produce different "values", and it is compatible in form with
the existing language.

-- Jim Balter, INTERACTIVE Systems (ima!jim)

ron@brl-tgr.ARPA (Ron Natalie <ron>) (11/05/84)

> >/* Written 12:37 pm  Oct 22, 1984 by ron@brl-tgr in ISM780B:net.lang.c */
> >> It seems to me that K&R guarantees that globals are initialized to zero,
> >> not to a nil pointer.  A lot of code will bite the dust given a machine
> >> with a non-zero nil pointer.
> >>
> >> -- Jim Balter, INTERACTIVE Systems (ima!jim)
> >
> >BUT that still doesn't make it legal to 0-> something.
> >
> >-Ron
> 
> I just love those non-sequiturs.  In case you hadn't noticed, *this*
> discussion is about whether NULL can be non-zero.
> 
The reason it appeared to be non-sequitur was because you left out the
rest of the context.  Your comment was a direct reply to another letter
and the topic of conversation was can I use &0->element to find out the
byte offset of element in the structure.

FOO.

henry@utzoo.UUCP (Henry Spencer) (11/06/84)

> What is wrong with
> 
> 	union foo thing.member = {...};
> 
> ?  It is clear and unambiguous.

I could mumble about irregular syntax and lack of implementation experience,
but this particular suggestion doesn't sound bad.  It eliminates the problems
of trying to guess a member name from a (possibly incomplete) indication of
type, and I don't *think* it would break anything.  The remaining questions
are (a) is it needed badly enough to bother?, and (b) can the ANSI folks be
convinced of this?  [Note that convincing me doesn't help; despite my habit
of taking the committee's side, I'm not a member of it.]
-- 
				Henry Spencer @ U of Toronto Zoology
				{allegra,ihnp4,linus,decvax}!utzoo!henry

henry@utzoo.UUCP (Henry Spencer) (11/06/84)

> Aside from the case of BSS initialization, which one could argue is equivalent
> to an assignment so the compiler can handle pointers by initializing them
> (good luck to people who depend on these variables really going into .bss),
> there is calloc and memset(&structure, '\0', sizeof structure); these
> would have to be changed to explicit member-by-member assignment,
> or assignment from a dummy previously initialized structure.

People who depend on specific variables really going into .bss are
writing grossly unportable code -- the whole *notion* of .bss is quite
implementation-dependent -- so I feel no sympathy for them.

calloc() is admittedly problematic, but one can argue that the definition
of calloc() is such that it is unimplementable on oddball machines.  That
is, the definition of calloc() is subtly machine-dependent.  Viewed in this
light, calloc() is a lesser issue.  Ditto for memset(), whatever in the
world that is.
-- 
				Henry Spencer @ U of Toronto Zoology
				{allegra,ihnp4,linus,decvax}!utzoo!henry