[comp.lang.c] negative addresses

tim@amdcad.AMD.COM (Tim Olson) (05/11/88)

Note: I am also including comp.lang.c, since this also pertains to C...

In article <2393@uvacs.CS.VIRGINIA.EDU>, wulf@uvacs.CS.VIRGINIA.EDU (Bill Wulf) writes:
| Has anyone ever seen a machine with "negative addresses", that is, one
| where the address space is -2**31..2**31-1 rather than 0..2*32-1??
| Any thoughts on what the problems with such a scheme might be (or are)?

I can't think of any real problems offhand, but this representation
affects a few things:

Your program's virtual address space probably starts at -2**31,
rather than 0 (to give you the full range).  This means that C-language
null pointers, because they are defined never to point to a valid
address, will probably have to be something other than the standard
all-zero bit representation.  This is not a real problem, as C allows
this.  However, it complicates the compiler somewhat (having to detect
the assignment/comparison of a pointer and the integer constant 0 as a
special case).  Also, buggy programs that used to run with references
through uninitialized static pointers might break in horrible ways (this
is not necessarily bad! ;-)

| Why ask such a question, you ask -- well, I'm trying to remove unsigned
| arithmetic from WM, and as far as I can tell, the primary (only?) use
| of unsigned arithmetic is for address computations. Soooooo...

What about support for explicit unsigned types in HLLs?  This would only
work if you limited the range of "unsigned" values to 0..2**31-1, rather
than the full 32-bit range.  However, my copy of the ANSI C Draft Spec
(which might be out of date) says:

	"For |signed char| and each type of |int|, there is a
	corresponding unsigned type (declared with the keyword
	|unsigned|) that utilizes the same amount of storage including
	sign information.  The set of nonnegative values of a signed
	type is a subset of its corresponding unsigned type."

	-- Tim Olson
	Advanced Micro Devices
	(tim@delirun.amd.com)

henry@utzoo.uucp (Henry Spencer) (05/12/88)

> Your program's virtual address space probably starts at -2**31,
> rather than 0 (to give you the full range).  This means that C-language
> null pointers, because they are defined never to point to a valid
> address, will probably have to be something other than the standard
> all-zero bit representation.  This is not a real problem...

Unfortunately, it is a real problem, because there are zillions of
programs that implicitly assume that pointers are all-zeros.  It is
true that the language does not require it, but doing anything else
is an enormous pain in practice, according to the people who have
experimented with the idea.

Fortunately the problem can be bypassed, because there is absolutely no
reason why the null pointer has to point to the beginning of your address
space.  It is sufficient for the machine and the memory allocator to
conspire to ensure that no user data is ever allocated at location 0.
This would qualify as a nuisance, but hardly a disaster.

> ... it complicates the compiler somewhat (having to detect
> the assignment/comparison of a pointer and the integer constant 0 as a
> special case)...

Not by much.  Some machines already need such complications because their
pointers and integers are not the same size.

> ... uninitialized static pointers might break in horrible ways (this
> is not necessarily bad! ;-)

Are you going to fix all the programs that rely on it? ;-)  More to the
point, this is not an issue, because uninitialized static variables are
*not* initialized to all-zeros, they are initialized to the zero value
of their data type, which means the null pointer for pointers.  Now this
would be a bit of a pain for compilers on machines with odd representations
of the null pointer.
-- 
NASA is to spaceflight as            |  Henry Spencer @ U of Toronto Zoology
the Post Office is to mail.          | {ihnp4,decvax,uunet!mnetor}!utzoo!henry

gwyn@brl-smoke.ARPA (Doug Gwyn ) (05/14/88)

In article <1988May12.162906.16901@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
>Unfortunately, it is a real problem, because there are zillions of
>programs that implicitly assume that pointers are all-zeros.

I don't think this is true.  How about an example?

>... uninitialized static variables are
>*not* initialized to all-zeros, they are initialized to the zero value
>of their data type, which means the null pointer for pointers.  Now this
>would be a bit of a pain for compilers on machines with odd representations
>of the null pointer.

Not that much of a problem, really.  The compiler knows about static
data at compile time, and if not explicitly initialized it can output
something like
	ptrname: .word 0xF0F0F0F0 ; null pointer pattern
in the data section of the code it generates.

henry@utzoo.uucp (Henry Spencer) (05/16/88)

> >Unfortunately, it is a real problem, because there are zillions of
> >programs that implicitly assume that pointers are all-zeros.
> 
> I don't think this is true.  How about an example?

Any program written by a programmer who believes the 4.3BSD manuals, or
any of their ancestors, all of which claim that the arg-list terminator
for execl is 0 rather than (char *)0.  A pox on the Berkloids for not
having fixed this long ago!

I'm not intimately acquainted with the problem myself, but I do know that
at least one computer project that wanted to use a non-zero null pointer
studied the situation and decided to change the hardware instead.

>Not that much of a problem, really.  The compiler knows about static
>data at compile time, and if not explicitly initialized it can output
>something like
>	ptrname: .word 0xF0F0F0F0 ; null pointer pattern
>in the data section of the code it generates.

True, which is why I described it as "a bit of a pain" rather than as
a significant problem.  The biggest nuisance, actually, is the loss in
effectiveness of the "BSS" optimization for object-module size.
-- 
NASA is to spaceflight as            |  Henry Spencer @ U of Toronto Zoology
the Post Office is to mail.          | {ihnp4,decvax,uunet!mnetor}!utzoo!henry

karl@haddock.ISC.COM (Karl Heuer) (05/17/88)

In article <1988May15.222335.13174@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
>The biggest nuisance, actually, [with a nonzero representation for NULL] is
>the loss in effectiveness of the "BSS" optimization for object-module size.

One could implement separate segments for "integral BSS", "pointer BSS", and
"floating BSS".  Mixed-type aggregate BSS would still be the compiler's
responsibility, unless you have a really smart object format.

You'd probably also catch a few programs that (improperly) assume that
"int x; char *y;" allocates adjacent memory cells.

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
(In the above, "BSS" means "uninitialized static-duration data".)
--> Followup cautiously -- this article is still cross-posted <--

yuhara@ayumi.stars.flab.fujitsu.JUNET (== M. Yuhara ==) (05/17/88)

In article <2393@uvacs.CS.VIRGINIA.EDU>, wulf@uvacs.CS.VIRGINIA.EDU (Bill Wulf) writes:
> Has anyone ever seen a machine with "negative addresses", that is, one
> where the address space is -2**31..2**31-1 rather than 0..2*32-1??

Yes, yes.
TRON chip deals an address as an signed integer.
On TRONCHIP32, -2**31..-1 is called Shared-semi-Space (SS) which is shared
among processes. 0..2**31-1 is called Unshared-semi-Space (US) which is
independent among processes.
(You can think of SS as System's Space, and US as User's Space).

TRON chip architecture is designed to be extensible from 32 bit address space
through 48 (TRONCHIP48) to 64 bit address space (TRONCHIP64).

If you think SS is 2**31..2*32-1, you will have difficulty when you
extend address space. But if you think it is signed, address space can
be extended naturally.

		-2**63	+---------+
		   /	|         |
		 /	|         |
		/	|         |
	       /	|         |
-2GB+---------+ -2**31  |         |
    |  SS     |         |   SS    |
    |         |         |         |  <-- Some system parameters stay here.
  0 +=========+       0 +=========+      (such as reset vector.)
    |         |         |         |
    |  US     |         |         |
+2GB+---------+ 2**31-1 |   US    |
	       \    	|	  |
		\	|         |
		 \	|         |
		   \	|         |
		2**63-1	+---------+




-- 
Artifitial Intelligence Division
Fujitsu Laboratories LTD., Kawasaki, Japan.
Masanobu YUHARA
kddlab!yuhara%flab.flab.fujitsu.junet@uunet.UU.NET

andrew@frip.gwd.tek.com (Andrew Klossner) (05/18/88)

Doug Gwyn (gwyn@brl-smoke.ARPA) writes:

>> Unfortunately, it is a real problem, because there are zillions of
>> programs that implicitly assume that [null] pointers are all-zeros.

> I don't think this is true.  How about an example?

Sure Doug, from the system V kernel that you defend so ardently :-),
file io/tt1.c (vanilla release 3.1):

In routine ttout:

		if (tbuf->c_ptr)

appears twice.  (And in the same routine,

		if (tbuf->c_ptr == NULL)

appears twice.  Multiple hackers have clogged through here.)

In routine ttioctl:

		if (tp->t_rbuf.c_ptr) {
		if (tp->t_tbuf.c_ptr) {

The C standards I've seen so far are pretty clear in stating that the
conditional is compared against zero.  There doesn't seem to be leeway
to define pointer comparisons to be against some non-zero NULL value.

  -=- Andrew Klossner   (decvax!tektronix!tekecs!andrew)       [UUCP]
                        (andrew%tekecs.tek.com@relay.cs.net)   [ARPA]

mouse@mcgill-vision.UUCP (der Mouse) (05/18/88)

In article <10001@tekecs.TEK.COM>, andrew@frip.gwd.tek.com (Andrew Klossner) writes:
> Doug Gwyn (gwyn@brl-smoke.ARPA) writes:
[an attribution appears to have been lost, but presumably it's our
friend Andrew Klossner]
>>> Unfortunately, it is a real problem, because there are zillions of
>>> programs that implicitly assume that [null] pointers are all-zeros.
>> I don't think this is true.  How about an example?
> Sure Doug, from the system V kernel that you defend so ardently :-),
> file io/tt1.c (vanilla release 3.1):
> 		if (tbuf->c_ptr)
> 		if (tbuf->c_ptr == NULL)
> 		if (tp->t_rbuf.c_ptr) {
> 		if (tp->t_tbuf.c_ptr) {

> The C standards I've seen so far are pretty clear in stating that the
> conditional is compared against zero.  There doesn't seem to be
> leeway to define pointer comparisons to be against some non-zero NULL
> value.

But when a pointer is compared against the integer constant zero,
either explicitly (second example) or implicitly (other three
examples), the zero is cast to the appropriate pointer type, producing
whatever bit pattern is appropriate for a null pointer of that type.
(Similar things happen when assigning the integer constant zero to a
pointer.  Note that "integer constant zero" is not the same thing as
"integer expression with value zero".)  This was true in K&R and
remains true in the dpANS.

					der Mouse

			uucp: mouse@mcgill-vision.uucp
			arpa: mouse@larry.mcrcim.mcgill.edu

faustus@ic.Berkeley.EDU (Wayne A. Christopher) (05/18/88)

In article <10001@tekecs.TEK.COM>, andrew@frip.gwd.tek.com (Andrew Klossner) writes:
> >> Unfortunately, it is a real problem, because there are zillions of
> >> programs that implicitly assume that [null] pointers are all-zeros.
> 
> 		if (tbuf->c_ptr)

The trick here is that whenever a pointer is converted into an
integer (as here), the NULL pointer must be converted to the integer
0.  It doesn't matter what the bit pattern is before conversion.
Otherwise, as you say, the world would be swallowed up by huge
tidal waves and the sun would fall from the sky.  Are there any
implementations of C that use a non-0 bit pattern?  I pity the
compiler writer...

	Wayne

gwyn@brl-smoke.ARPA (Doug Gwyn ) (05/18/88)

In article <10001@tekecs.TEK.COM> andrew@frip.gwd.tek.com (Andrew Klossner) writes:
-Doug Gwyn (gwyn@brl-smoke.ARPA) writes:
->> Unfortunately, it is a real problem, because there are zillions of
->> programs that implicitly assume that [null] pointers are all-zeros.
-> I don't think this is true.  How about an example?
-		if (tbuf->c_ptr)
-		if (tbuf->c_ptr == NULL)
-		if (tp->t_rbuf.c_ptr) {
-		if (tp->t_tbuf.c_ptr) {

None of these are non-portable uses of C; none of them depend on
null pointers being represented by all-zero data.

I'm still waiting for an example...

gwyn@brl-smoke.ARPA (Doug Gwyn ) (05/18/88)

In article <3504@pasteur.Berkeley.Edu> faustus@ic.Berkeley.EDU (Wayne A. Christopher) writes:
>In article <10001@tekecs.TEK.COM>, andrew@frip.gwd.tek.com (Andrew Klossner) writes:
>> 		if (tbuf->c_ptr)
>The trick here is that whenever a pointer is converted into an
>integer (as here), the NULL pointer must be converted to the integer
>0.  It doesn't matter what the bit pattern is before conversion.

You got the right answer by the wrong reasoning.
The pointer is NOT converted to an integer.
This partial-statement is fully equivalent to
	if (tbuf->c_ptr != 0)
and the integer constant 0 is guaranteed to
be comparable to a null pointer.  How this is
accomplished is the implementor's business,
and does NOT imply that a null pointer of a
given type (there are different pointer types!)
is represented in a way that "looks like" the
representation of integer value 0.

tim@amdcad.AMD.COM (Tim Olson) (05/18/88)

In article <10001@tekecs.TEK.COM> andrew@frip.gwd.tek.com (Andrew Klossner) writes:
| Doug Gwyn (gwyn@brl-smoke.ARPA) writes:
| 
| >> Unfortunately, it is a real problem, because there are zillions of
| >> programs that implicitly assume that [null] pointers are all-zeros.
| 
| > I don't think this is true.  How about an example?
| 
| Sure Doug, from the system V kernel that you defend so ardently :-),
| file io/tt1.c (vanilla release 3.1):
| 
| In routine ttout:
| 
| 		if (tbuf->c_ptr)
| 
| appears twice.  (And in the same routine,
| 
| 		if (tbuf->c_ptr == NULL)
| 
| appears twice.  Multiple hackers have clogged through here.)
| 
| In routine ttioctl:
| 
| 		if (tp->t_rbuf.c_ptr) {
| 		if (tp->t_tbuf.c_ptr) {
| 
| The C standards I've seen so far are pretty clear in stating that the
| conditional is compared against zero.  There doesn't seem to be leeway
| to define pointer comparisons to be against some non-zero NULL value.

"NULL" wasn't being discussed, it was the internal representation of null
pointers (this seems to cause so much confusion -- how about calling the
latter a different name, like "nil"?).

As has been stated in comp.lang.c numerous times: in C, nil can be any
bit pattern, as long as it is guaranteed not to ever point to valid
data.  NULL must be 0 (or perhaps (void *)0 under ANSI).  The compiler
takes care of the appropriate conversions between NULL and nil.  The
above code is correct C.

	-- Tim Olson
	Advanced Micro Devices
	(tim@amdcad.amd.com)

sarima@gryphon.CTS.COM (Stan Friesen) (05/19/88)

In article <10001@tekecs.TEK.COM> andrew@frip.gwd.tek.com (Andrew Klossner) writes:
>Doug Gwyn (gwyn@brl-smoke.ARPA) writes:
>
>> I don't think this is true.  How about an example?
[[Of code assuming the null pointer is all zero bits]]
>
>Sure Doug, from the system V kernel that you defend so ardently :-),
>file io/tt1.c (vanilla release 3.1):
>
>		if (tbuf->c_ptr)
>
>		if (tbuf->c_ptr == NULL)
>
>		if (tp->t_rbuf.c_ptr) {
>		if (tp->t_tbuf.c_ptr) {
>
>The C standards I've seen so far are pretty clear in stating that the
>conditional is compared against zero.  There doesn't seem to be leeway
>to define pointer comparisons to be against some non-zero NULL value.

	Yes, but they ALSO require that comparing a NULL-pointer to zero
evaluate to true *whatever* the representation of the NULL-pointer. The
compiler is *also* required to convert the integer constant 0 to the
NULL-pointer on assignment. So *none* of the above examples assume anything
about the representation of the NULL-pointer, they are all strictly
conforming. There *are* cases of code that does make such assumptions.
They all have the following general form:

func1(p)
char *p;
{
	/* stuff */
}

...

func2()
{
	...
	func1(0);
}

	In this example the code assumes both the representation *and* the
size of NULL-pointer. This code is *not* portable even among existing
compilers. Nor is it even conforming, let alone strictly so. Any code of
this form only works accidentally and needs to be fixed anyway.
-- 
Sarima Cardolandion			sarima@gryphon.CTS.COM
aka Stanley Friesen			rutgers!marque!gryphon!sarima
					Sherman Oaks, CA

henry@utzoo.uucp (Henry Spencer) (05/20/88)

>		if (tp->t_tbuf.c_ptr) {
>The C standards I've seen so far are pretty clear in stating that the
>conditional is compared against zero.  There doesn't seem to be leeway
>to define pointer comparisons to be against some non-zero NULL value.

Sigh.  Not this again!  If you *read* the fine print in the standards,
you will find that this construct is 100.00000% equivalent to saying
"if (tp->t_tbuf.c_ptr != NULL) {".  In pointer contexts, which this
is, the integer constant 0 stands for "whatever bit pattern is used for
null pointers".  When p is a pointer, "if (p)", "if (p != 0)" and
"if (p != NULL)" are completely synonymous, by the definition of C.

The problem that does come up is that compilers in general cannot tell
whether a parameter in a function call is meant to be a pointer or not,
and hence cannot supply the automatic conversion.  There is also trouble
with programs that explicitly convert pointers to integers and back.
-- 
NASA is to spaceflight as            |  Henry Spencer @ U of Toronto Zoology
the Post Office is to mail.          | {ihnp4,decvax,uunet!mnetor}!utzoo!henry

phil@osiris.UUCP (Philip Kos) (05/20/88)

In article <4086@gryphon.CTS.COM>, sarima@gryphon.CTS.COM (Stan Friesen) writes:
> In article <10001@tekecs.TEK.COM> andrew@frip.gwd.tek.com (Andrew Klossner) writes:
> > There doesn't seem to be leeway
> >to define pointer comparisons to be against some non-zero NULL value.
> 
> 	Yes, but they ALSO require that comparing a NULL-pointer to zero
> evaluate to true *whatever* the representation of the NULL-pointer....

Please be careful not to confuse null pointers with NULL pointers.  Null
pointers have a formal definition within the language, but NULL pointers
don't really; NULL is just a convention and not part of the language spec.
("We write NULL instead of zero, however, to indicate more clearly that
this is a special value for a pointer", K&R first edition, pp. 97-98; "The
symbolic constant NULL is often used in place of zero, as a mnemonic to
indicate more clearly that this is a special value for a pointer", K&R
second edition, p. 102.)

I've also seen NULL defined as (char *) 0, by the way...


                                                                 Phil Kos
                                                      Information Systems
...!uunet!pyrdc!osiris!phil                    The Johns Hopkins Hospital
                                                            Baltimore, MD

radford@calgary.UUCP (Radford Neal) (05/20/88)

In article <10001@tekecs.TEK.COM>, andrew@frip.gwd.tek.com (Andrew Klossner) writes:

> >> Unfortunately, it is a real problem, because there are zillions of
> >> programs that implicitly assume that [null] pointers are all-zeros.
> 
> > I don't think this is true.  How about an example?
> 
> Sure Doug, from the system V kernel... In routine ttout:
> 
> 		if (tbuf->c_ptr)

My understanding is that this is standards-conforming and portable.
I assume that c_ptr is declared to be of pointer type. The above 
statement is equivalent to

		if (tbuf->c_ptr!=0)

which is equivalent to

		if (tbuf->c_ptr!=(char*)0)

(or (int*)0 or whatever). The expression (char*)0 is _defined_ to be
the null pointer, whatever its bit pattern may be. Note that "NULL"
has nothing to do with anything, being merely a macro found in the
<stdio.h> include file.

An example of a non-portable program is the following:

    char *p;
    int i;
    ...
    i = (int)p;
    if (i!=0)
       *p = ...; /* no guarantee that p is not null... */

Only occurences of 0 in the explicit or implicit context (...*) 0
are magically converted to null pointers.

    Radford Neal

woerz@iaoobelix.UUCP (Dieter Woerz) (05/20/88)

In article <10001@tekecs.TEK.COM> andrew@frip.gwd.tek.com (Andrew Klossner) writes:
> ...
>In routine ttout:
>
>		if (tbuf->c_ptr)
>
>appears twice.  (And in the same routine,
>
>		if (tbuf->c_ptr == NULL)
>
>appears twice.  Multiple hackers have clogged through here.)
>
>In routine ttioctl:
>
>		if (tp->t_rbuf.c_ptr) {
>		if (tp->t_tbuf.c_ptr) {
> ...

I have to admit, that the others may not work, but I think you should
be able to tweak the compilers for that architecture to do a
comparision of such pointers with the Zero-Pointer of that
architecture, which is not necessaryly zero.

The second example is should work simply if you redefine NULL to the
value of the Zero-Pointer.

------------------------------------------------------------------------------

Dieter Woerz
Fraunhofer Institut fuer Arbeitswirtschaft und Organisation
Abt. 453
Holzgartenstrasse 17
D-7000 Stuttgart 1
W-Germany

BITNET: iaoobel.uucp!woerz@unido.bitnet
UUCP:   ...{uunet!unido, pyramid}!iaoobel!woerz

flaps@dgp.toronto.edu (Alan J Rosenthal) (05/22/88)

Henry Spencer wrote:
>>Unfortunately, it is a real problem, because there are zillions of
>>programs that implicitly assume that pointers are all-zeros.

Doug Gwyn replied:
>I don't think this is true.  How about an example?

Later, he wrote that he was still waiting for an example, so I'll provide one.

A large project on which I am currently working has many segments in
which lists of things are manipulated; to a large extent mostly for
displaying in menus, but also for other standard data processing kinds
of tasks.  There is a standardised doubly-linked list representation,
and corresponding routines.  The caller of these routines has as its
representation of the list a "head" which contains header-like
information for the list.

When I first tried to use these routines, I looked through and found
out how to do various operations.  The operation I could not find was
how to initialise a doubly-linked list after having declared the head.
It turned out that a correct initialisation was to set the three
pointers in a struct dll_head all to NULL.  Since existing code usually
happened to declare the head as either global or file static most
people forgot to bother to initialise the head.  When one was declared
as auto, people called zero((char *)&thing,sizeof(struct dll_head)),
zero() being a function which sets a region of memory to zero bits.

So there's your example.

[We have since added an initialisation function!]

ajr

--
- Any questions?
- Well, I thought I had some questions, but they turned out to be a trigraph.

bill@proxftl.UUCP (T. William Wells) (05/23/88)

In article <10001@tekecs.TEK.COM>, andrew@frip.gwd.tek.com (Andrew Klossner) writes:
> Doug Gwyn (gwyn@brl-smoke.ARPA) writes:
>
> >> Unfortunately, it is a real problem, because there are zillions of
> >> programs that implicitly assume that [null] pointers are all-zeros.
>
> > I don't think this is true.  How about an example?
>
> Sure Doug, from the system V kernel that you defend so ardently :-),
> file io/tt1.c (vanilla release 3.1):
>
> In routine ttout:
>
>               if (tbuf->c_ptr)
>
> appears twice.  (And in the same routine,
>
>               if (tbuf->c_ptr == NULL)

ANSI says that the two are equivalent.  Actually, ANSI says
(about `if'): "...  the first substatement is executed if the
expression compares unequal to 0.  ...".  This means that you can
think of the statement `if (x)' as `if (x != 0)'.

Note that ANSI only insists that `pointer == 0' be true if and
only if pointer is a null pointer; it makes no requirements that
the pointer actually contain any zeros.

For example, on an 8086, you could define a null pointer as one
with a zero (or any other value) offset.  An implicit or explicit
compare of the pointer to zero would then check only the offset.

An interesting point: ANSI does not define (at least not anywhere
I can find it) the result of `x == y' when x and y are both null
pointers.  Actually, a literal reading of the standard implies
that this would compare false!  Here is my reasoning.  The
standard says that "If two pointers ...  compare equal, they
point to the same object." Since a null pointer does not point to
ANY object, comparing anything to a null pointer should return
false.

I hope that this is an oversight.

paul@unisoft.UUCP (n) (05/23/88)

In article <206@proxftl.UUCP> bill@proxftl.UUCP (T. William Wells) writes:
>>
>>               if (tbuf->c_ptr == NULL)
>
>ANSI says that the two are equivalent.  Actually, ANSI says
>(about `if'): "...  the first substatement is executed if the
>expression compares unequal to 0.  ...".  This means that you can
>think of the statement `if (x)' as `if (x != 0)'.
>

Correct me if I'm wrong .....

			   if (x) ...

	really means 	   if (x != 0) ....
	which really means if ((x != 0) != 0) ...
	which really means if (((x != 0) != 0) != 0) ...
	which really means if ((((x != 0) != 0) != 0) != 0) ...

				etc etc


hence the need for all these new super optimising compilers .....


		Paul

	
-- 
Paul Campbell, UniSoft Corp. 6121 Hollis, Emeryville, Ca
	E-mail:		..!{ucbvax,hoptoad}!unisoft!paul  
Nothing here represents the opinions of UniSoft or its employees (except me)
"Nuclear war doesn't prove who's Right, just who's Left" (ABC news 10/13/87)

djones@megatest.UUCP (Dave Jones) (05/24/88)

in article <959@unisoft.UUCP}, paul@unisoft.UUCP (n) says:

} 			   if (x) ...
} 
} 	really means 	   if (x != 0) ....
} 	which really means if ((x != 0) != 0) ...
} 	which really means if (((x != 0) != 0) != 0) ...
} 	which really means if ((((x != 0) != 0) != 0) != 0) ...
} 
} 				etc etc
} 
} 
} hence the need for all these new super optimising compilers .....
} 


Love it.  You made my day.

Have you ever put two packages together, and cpp says "FALSE redefined"?

That means that not one, but TWO, count 'em, TWO .h files have a
macro like

#define FALSE (0!=0)

and they aren't the same.

In the code, you're likely to see 

	if( x == FALSE )

which translates to

	if( x == (0!=0) )

which, in C,  ain't the same as if( !x ).  I call this the
"Law of the Included Muddle".

Now if they had just written the macro that way, we'd have this:

#define FALSE ((0!=0)!=FALSE)

Now we've *really* got something for your optimizing compilers to crunch on.

  if(x != ((0!=0)!=((0!=0)!=((0!=0)!= ... 

I wonder if the TRUE-believers figure that someday they'll need to redefine
TRUE to -- oh let's see -- maybe 42?



		-- Dave J.

bill@proxftl.UUCP (T. William Wells) (05/28/88)

In article <4086@gryphon.CTS.COM>, sarima@gryphon.CTS.COM (Stan Friesen) writes:
)             There *are* cases of code that does make such assumptions.
) They all have the following general form:
)
) func1(p)
) char *p;
) {
)       /* stuff */
) }
)
) ...
)
) func2()
) {
)       ...
)       func1(0);
) }
)
)       In this example the code assumes both the representation *and* the
) size of NULL-pointer. This code is *not* portable even among existing
) compilers. Nor is it even conforming, let alone strictly so. Any code of
) this form only works accidentally and needs to be fixed anyway.
) --
) Sarima Cardolandion                   sarima@gryphon.CTS.COM
) aka Stanley Friesen                   rutgers!marque!gryphon!sarima

Actually, if you are using Standard C, declare func1 with a prototype
and the problem goes away. Prototypes were invented to (among other
things) solve this kind of problem.

Perhaps this is what you intended to say?

ericb@athertn.Atherton.COM (Eric Black) (06/02/88)

In article <8805220452.AA14606@explorer.dgp.toronto.edu> flaps@dgp.toronto.edu (Alan J Rosenthal) writes:
>
>Henry Spencer wrote:
>>>Unfortunately, it is a real problem, because there are zillions of
>>>programs that implicitly assume that pointers are all-zeros.
>
>Doug Gwyn replied:
>>I don't think this is true.  How about an example?
>
>Later, he wrote that he was still waiting for an example, so I'll provide one.
> [...description of linked list of nodes pointing to other nodes...]
>people forgot to bother to initialise the head.  When one was declared
>as auto, people called zero((char *)&thing,sizeof(struct dll_head)),
>zero() being a function which sets a region of memory to zero bits.
>
>So there's your example.

A wonderful example of non-portable code!  Essentially what you are doing
without making it explicit is punning the pointer, just as if you had
something like:
	union {
		long	ima_number;
		char	*ima_pointer;
	};
and set the bits via one union member, and looked at them via the other.

There are also "zillions of programs" that assume the order of characters
in a long, and break when moved from a VAX to a 68K, or other analogous move.

Such code should be punishable by forcing the programmer to port C programs
running under UNIX to run under PRIMOS.  (no :-)

>
>[We have since added an initialisation function!]
>
>ajr

Huzzah!  What happens now when people "forget to bother to initialise the
head"??  Buggy code is an existence proof for buggy code...  A non-portable
"safety net" for programmers of said buggy code doesn't seem to me to be
a whole lot different than device drivers that assume that all device
control and status registers look exactly like the CSR on Unibus devices;
both might be perfectly valid in the environment they assume, but are
quite wrong when taken out of that environment.

Note that such assumptions are not just machine-dependent; they can also
be compiler-dependent!

I hope there was a :-) truncated by NNTP in your article...

:-):-):-):-):-):-):-):-):-):-):-):-):-):-):-):-):-):-):-):-):-):-):-):-):-)


-- 
Eric Black	"Garbage in, Gospel out"
Atherton Technology, 1333 Bordeaux Dr., Sunnyvale, CA, 94089
   UUCP:	{sun,decwrl,hpda,pyramid}!athertn!ericb
   Domainist:	ericb@Atherton.COM