By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,874 Members | 1,027 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,874 IT Pros & Developers. It's quick & easy.

memset all bits to zero will let float/double to zero?

P: n/a
Hi, All
I am reading FAQ of this group. I have a question about this:
http://www.eskimo.com/~scs/C-faq/q7.31.html

It says:
"
p = malloc(m * n);
memset(p, 0, m * n);
The zero fill is all-bits-zero, and does not therefore guarantee useful null
pointer values (see section 5 of this list) or floating-point zero values.
"

but ieee754 defined float zero to be all-bits-zero.

Anyone can help to explain about this?

Thanks in advance.
Nov 14 '05 #1
Share this Question
Share on Google+
53 Replies


P: n/a
In article <ca***********@mail.cn99.com>,
Zhiqiang Ye <ye**@mail.cbi.pku.edu.cn> wrote:
The zero fill is all-bits-zero, and does not therefore guarantee useful null
pointer values (see section 5 of this list) or floating-point zero values. but ieee754 defined float zero to be all-bits-zero.


So *if* your C omplementation uses IEEE floating point, the values will
be zero.

-- Richard
Nov 14 '05 #2

P: n/a
Zhiqiang Ye wrote:
I am reading FAQ of this group. I have a question about this:
http://www.eskimo.com/~scs/C-faq/q7.31.html

It says:
"
p = malloc(m * n);
memset(p, 0, m * n);
The zero fill is all-bits-zero, and does not therefore guarantee useful null
pointer values (see section 5 of this list) or floating-point zero values.
"

but ieee754 defined float zero to be all-bits-zero.

Anyone can help to explain about this?


Here's a wild guess.

Because IEEE 754 support is not mandatory? Thus you cannot, portably,
assume that every compiler will implement the formats specified by the
IEEE 754 standard.

Nov 14 '05 #3

P: n/a
In <ca***********@mail.cn99.com> "Zhiqiang Ye" <ye**@mail.cbi.pku.edu.cn> writes:
I am reading FAQ of this group. I have a question about this:
http://www.eskimo.com/~scs/C-faq/q7.31.html

It says:
"
p = malloc(m * n);
memset(p, 0, m * n);
The zero fill is all-bits-zero, and does not therefore guarantee useful null
pointer values (see section 5 of this list) or floating-point zero values.
"

but ieee754 defined float zero to be all-bits-zero.

Anyone can help to explain about this?


The C standard doesn't say that floating point types *must* follow the
IEEE-754 specification. There are other floating point representations
where all bits zero doesn't mean zero.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #4

P: n/a
Zhiqiang Ye wrote:
Hi, All
I am reading FAQ of this group. I have a question about this:
http://www.eskimo.com/~scs/C-faq/q7.31.html

It says:
"
p = malloc(m * n);
memset(p, 0, m * n);
The zero fill is all-bits-zero, and does not therefore guarantee useful
null pointer values (see section 5 of this list) or floating-point zero
values. "

but ieee754 defined float zero to be all-bits-zero.

Anyone can help to explain about this?


C doesn't require implementations to use IEEE754, if I recall correctly.

--
Chris "electric hedgehog" Dollin
C FAQs at: http://www.faqs.org/faqs/by-newsgrou...mp.lang.c.html
C welcome: http://www.angelfire.com/ms3/bchambl...me_to_clc.html
Nov 14 '05 #5

P: n/a
Zhiqiang Ye <ye**@mail.cbi.pku.edu.cn> wrote:
Hi, All
I am reading FAQ of this group. I have a question about this:
http://www.eskimo.com/~scs/C-faq/q7.31.html

It says:
"
p = malloc(m * n);
memset(p, 0, m * n);
The zero fill is all-bits-zero, and does not therefore guarantee useful null
pointer values (see section 5 of this list) or floating-point zero values.
"

but ieee754 defined float zero to be all-bits-zero.

Anyone can help to explain about this?


Very simple. There are other floating-point formats than those defined
in IEEE754. The C standard does not guarantee or require that IEEE754
is used.
--
<Insert your favourite quote here.>
Erik Trulsson
er******@student.uu.se
Nov 14 '05 #6

P: n/a
In <ca**********@news-rocq.inria.fr> Grumble <a@b.c> writes:
Zhiqiang Ye wrote:
I am reading FAQ of this group. I have a question about this:
http://www.eskimo.com/~scs/C-faq/q7.31.html

It says:
"
p = malloc(m * n);
memset(p, 0, m * n);
The zero fill is all-bits-zero, and does not therefore guarantee useful null
pointer values (see section 5 of this list) or floating-point zero values.
"

but ieee754 defined float zero to be all-bits-zero.

Anyone can help to explain about this?


Here's a wild guess.

Because IEEE 754 support is not mandatory? Thus you cannot, portably,
assume that every compiler will implement the formats specified by the
IEEE 754 standard.


IEEE 754 is particularly expensive when done in software, because the
underlying hardware provides no floating point support. Therefore,
implementations for such hardware either use a different floating point
format or provide two floating point representations: IEEE 754 and
something faster.

For example, MS C implementations for the 80[23]86 came with both
80[23]87 emulation (i.e. IEEE 754 implemented in software) and with an
implementation of a Microsoft-designed floating point format. The former
could transparently exploit an 80[23]87 chip, if present, the latter was
significantly faster on systems without an 80[23]87 chip, but couldn't
benefit from such a chip, if present.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #7

P: n/a
Zhiqiang Ye wrote:
I am reading FAQ of this group. I have a question about this:
http://www.eskimo.com/~scs/C-faq/q7.31.html

It says:
"
p = malloc(m * n);
memset(p, 0, m * n);
The zero fill is all-bits-zero, and does not therefore guarantee useful null
pointer values (see section 5 of this list) or floating-point zero values.
"

but ieee754 defined float zero to be all-bits-zero.

Anyone can help to explain about this?


IEEE 754 specification is not a part of C language specification.
Implementations are not required to conform to IEEE 754.

--
Best regards,
Andrey Tarasevich

Nov 14 '05 #8

P: n/a
>p = malloc(m * n);
memset(p, 0, m * n);
The zero fill is all-bits-zero, and does not therefore guarantee useful null
pointer values (see section 5 of this list) or floating-point zero values.
"

but ieee754 defined float zero to be all-bits-zero.


ieee754 defined two DIFFERENT floating point representations for zero,
and they can't both be all-bits-zero. Also, not everyone uses ieee754
floating point.

Gordon L. Burditt

Nov 14 '05 #9

P: n/a
In article <ca***********@mail.cn99.com>,
"Zhiqiang Ye" <ye**@mail.cbi.pku.edu.cn> wrote:
Hi, All
I am reading FAQ of this group. I have a question about this:
http://www.eskimo.com/~scs/C-faq/q7.31.html

It says:
"
p = malloc(m * n);
memset(p, 0, m * n);
The zero fill is all-bits-zero, and does not therefore guarantee useful null
pointer values (see section 5 of this list) or floating-point zero values.
"

but ieee754 defined float zero to be all-bits-zero.

Anyone can help to explain about this?


But C doesn't guarantee ieee754.
Nov 14 '05 #10

P: n/a
Zhiqiang Ye wrote:
I am reading FAQ of this group. I have a question about this:

http://www.eskimo.com/~scs/C-faq/q7.31.html

It says:

p = malloc(m*n);
memset(p, 0, m*n);

The zero fill is all-bits-zero and does not, therefore,
guarantee useful null pointer values (see section 5 of this list)
or floating-point zero values.

but ieee754 defined float zero to be all-bits-zero.

Anyone can help to explain about this?


I don't think that you need to worry about this.
Every floating-point implementation on every machine
to which you are likely to port your software
recognizes "all-zero-bits"
to be a representation of floating-point +0.0

Unlike Java, the C language standard does need to specify
the representation of null pointers of floating-point numbers
so it doesn't.
This leaves open the possibility that implementations (compilers)
may use some other representation.
But, there are no implementations of the C 89 or C99 standard
that use anything but all zero bits to represent NULL or +0.0.
Nov 14 '05 #11

P: n/a
go***********@burditt.org (Gordon Burditt) writes:
p = malloc(m * n);
memset(p, 0, m * n);
The zero fill is all-bits-zero, and does not therefore guarantee useful null
pointer values (see section 5 of this list) or floating-point zero values.
"

but ieee754 defined float zero to be all-bits-zero.


ieee754 defined two DIFFERENT floating point representations for zero,
and they can't both be all-bits-zero. Also, not everyone uses ieee754
floating point.


IEEE754 0.0 is not necessarily all-bits-zero, but all-bits-zero is
necessarily IEEE754 0.0.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #12

P: n/a
Da*****@cern.ch (Dan Pop) writes:
[...]
The C standard doesn't say that floating point types *must* follow the
IEEE-754 specification. There are other floating point representations
where all bits zero doesn't mean zero.


Are any such representations currently being used?

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #13

P: n/a
"E. Robert Tisdale" wrote:
.... snip ...
But, there are no implementations of the C 89 or C99 standard
that use anything but all zero bits to represent NULL or +0.0.


Obviously you have secured and exhaustively examined every std C
implementation on any machine whatsoever. Sounds like a lot of
work. Was this funded by NASA, and how did you determine that you
checked each and every one? Where did you put those myriad
systems?

Maybe we should all write NASA and ask for the report. The
exhaustive listing should be useful. Being government funded it
should be freely available.

While doing all this, how did you find time for trolling and
spewing misinformation?

--
fix (vb.): 1. to paper over, obscure, hide from public view; 2.
to work around, in a way that produces unintended consequences
that are worse than the original problem. Usage: "Windows ME
fixes many of the shortcomings of Windows 98 SE". - Hutchison
Nov 14 '05 #14

P: n/a
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Keith Thompson wrote:
| Da*****@cern.ch (Dan Pop) writes:
| [...]
|
|>The C standard doesn't say that floating point types *must* follow the
|>IEEE-754 specification. There are other floating point representations
|>where all bits zero doesn't mean zero.
|
|
| Are any such representations currently being used?
|

IIRC, my TI-83 calculator uses a packed BCD representation for the
mantissa and an 8-bit 2's compliment number for the (decimal) exponent.
I would imagine BCD is quite common in calculators. However, you get
lucky again as all bits zero still means zero and, FWIW, I don't believe
there is an ISO C compiler for it.

Ross
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFA0W/P9bR4xmappRARAvd8AJwNpS+6UpF2SFil/Dasb2/zJGolSACgtRyn
BwPyCXIFzRQQF6+mpAiXQxk=
=Z19n
-----END PGP SIGNATURE-----
Nov 14 '05 #15

P: n/a
> Are any such representations currently being used?

<laugh> No, none at all. It is just fun for the regulars to insist on
possibility even when all computers out there are using IEEE-754 or
IEEE-854.

Anarchist
Nov 14 '05 #16

P: n/a
In <ca********@library2.airnews.net> go***********@burditt.org (Gordon Burditt) writes:
p = malloc(m * n);
memset(p, 0, m * n);
The zero fill is all-bits-zero, and does not therefore guarantee useful null
pointer values (see section 5 of this list) or floating-point zero values.
"

but ieee754 defined float zero to be all-bits-zero.


ieee754 defined two DIFFERENT floating point representations for zero,
and they can't both be all-bits-zero.


This is irrelevant, if ieee754 implementations must support both of them
at the same time.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #17

P: n/a
In <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
Da*****@cern.ch (Dan Pop) writes:
[...]
The C standard doesn't say that floating point types *must* follow the
IEEE-754 specification. There are other floating point representations
where all bits zero doesn't mean zero.


Are any such representations currently being used?


Not that I know of. Those representations were usually used by software
implementations of floating point, which are today quasi-extinct (at
least on hosted implementations).

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #18

P: n/a
"Anarchist" <no******@nowhere.com> writes:
Are any such representations currently being used?


<laugh> No, none at all. It is just fun for the regulars to insist on
possibility even when all computers out there are using IEEE-754 or
IEEE-854.


The question was whether there are floating-point representations
being used in which all-bit-zero does not represent 0.0. So far,
nobody has cited one.

But it's certainly not the case that all computers out there are using
IEEE-754 or IEE-854. Non-IEEE representations are becoming less
common, but there's not extinct. VAXen, Cray vector systems, and IBM
mainframes all have their own floating-point formats predating the
IEEE standards.

It may (or may not) be possible for a future C standard to mandate
that all-bits-zero is a valid representation of 0.0 for floating-point
types. Mandating IEEE format won't be practical for a long time, if
ever.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #19

P: n/a
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.org> wrote:
But it's certainly not the case that all computers out there are using
IEEE-754 or IEE-854. Non-IEEE representations are becoming less
common, but there's not extinct. VAXen, Cray vector systems, and IBM
mainframes all have their own floating-point formats predating the
IEEE standards.


True, but do any of the ones you mention not have all-bits-zero -> 0.0?

-- Richard
Nov 14 '05 #20

P: n/a
ri*****@cogsci.ed.ac.uk (Richard Tobin) writes:
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.org> wrote:
But it's certainly not the case that all computers out there are using
IEEE-754 or IEE-854. Non-IEEE representations are becoming less
common, but there's not extinct. VAXen, Cray vector systems, and IBM
mainframes all have their own floating-point formats predating the
IEEE standards.


True, but do any of the ones you mention not have all-bits-zero -> 0.0?


For the VAX and Cray formats, 0.0 is represented as all-bits-zero
(confirmed just now by experiment). For the IBM mainframe format, I
think that's the case but I can't confirm it.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #21

P: n/a
In <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
For the VAX and Cray formats, 0.0 is represented as all-bits-zero
(confirmed just now by experiment).
The PDP-11 and VAX cases are still well documented.
For the IBM mainframe format, I
think that's the case but I can't confirm it.


Given the nature of IBM's representation (no "hidden" mantissa bits),
any all zeros mantissa should be a representation of zero, unless
it's a trap representation (I don't remember IBM 360 floating point
actually using any trap representations).

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #22

P: n/a
In <ca***********@pc-news.cogsci.ed.ac.uk> ri*****@cogsci.ed.ac.uk (Richard Tobin) writes:
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.org> wrote:
But it's certainly not the case that all computers out there are using
IEEE-754 or IEE-854. Non-IEEE representations are becoming less
common, but there's not extinct. VAXen, Cray vector systems, and IBM
mainframes all have their own floating-point formats predating the
IEEE standards.


True, but do any of the ones you mention not have all-bits-zero -> 0.0?


The obvious candidate for all-bits-zero != 0.0 is a binary representation
with "hidden" mantissa bit that doesn't use excess-whatever for the
exponent. On such a representation, all-bits-zero would be 1.0 or 0.5,
depending on the position of the "binary point". 0.0 would either not
be exactly representable (no big deal) or use a bit pattern with the
exponent set to its minimum value.

I am not aware of any hardware implementation of such a representation,
but I'm not sure that I haven't seen/used at least one software
implementation like this.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #23

P: n/a
In article <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
ri*****@cogsci.ed.ac.uk (Richard Tobin) writes:
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.org> wrote:
But it's certainly not the case that all computers out there are using
IEEE-754 or IEE-854. Non-IEEE representations are becoming less
common, but there's not extinct. VAXen, Cray vector systems, and IBM
mainframes all have their own floating-point formats predating the
IEEE standards.


True, but do any of the ones you mention not have all-bits-zero -> 0.0?


For the VAX and Cray formats, 0.0 is represented as all-bits-zero
(confirmed just now by experiment). For the IBM mainframe format, I
think that's the case but I can't confirm it.


The only computer I have used that did have 0.0 with not all bits zero
was the CDC Cyber 205. I understand that the f-p format it used is the
same as in some MIL-STD computer.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Nov 14 '05 #24

P: n/a

"Dan Pop" <Da*****@cern.ch> wrote in message
news:ca**********@sunnews.cern.ch...
In <ca***********@pc-news.cogsci.ed.ac.uk> ri*****@cogsci.ed.ac.uk (Richard Tobin) writes:
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.org> wrote:
But it's certainly not the case that all computers out there are using
IEEE-754 or IEE-854. Non-IEEE representations are becoming less
common, but there's not extinct. VAXen, Cray vector systems, and IBM
mainframes all have their own floating-point formats predating the
IEEE standards.


True, but do any of the ones you mention not have all-bits-zero -> 0.0?


The obvious candidate for all-bits-zero != 0.0 is a binary representation
with "hidden" mantissa bit that doesn't use excess-whatever for the
exponent. On such a representation, all-bits-zero would be 1.0 or 0.5,
depending on the position of the "binary point". 0.0 would either not
be exactly representable (no big deal) or use a bit pattern with the
exponent set to its minimum value.

I am not aware of any hardware implementation of such a representation,
but I'm not sure that I haven't seen/used at least one software
implementation like this.

On a machine with no bias in the exponent, without a hidden mantissa bit,
all-bits-zero is an un-normalized floating point zero. As such machines did
not have gradual underflow, performing arithmetic between such operands and
other operands of magnitude < 0.5 gave truncated results. For example, had
<float.h> been implemented at that time, 0.9*LDBL_EPSILON + <all-bits-zero>
would give 0.0. One of the early C implementations (gcos) was on such a
machine. I over-simplify, since "long double" was not supported as a memory
storage data type, only in register.
Nov 14 '05 #25

P: n/a
Just to add to the confusion, there are really two different questions
here. One, the issue raised by the OP, is whether using memset to
assign all-bits-zero to a floating-point object will result in a value
equal to 0.0. The other is whether assigning the value 0.0 to a
floating-point object will result in the object containing
all-bits-zero.

The possible existence of multiple representations for 0.0 means that
these are not the same question. However, I'd be very surprised if
there were an implementation for which these questions have different
answers. In other words, I'm guessing that if all-bits-zero is a
valid representation of 0.0, it's the default representation of 0.0
(for each floating-point type in each implementation).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #26

P: n/a
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.org> wrote:
Just to add to the confusion, there are really two different questions
here. One, the issue raised by the OP, is whether using memset to
assign all-bits-zero to a floating-point object will result in a value
equal to 0.0. The other is whether assigning the value 0.0 to a
floating-point object will result in the object containing
all-bits-zero.

The possible existence of multiple representations for 0.0 means that
these are not the same question. However, I'd be very surprised if
there were an implementation for which these questions have different
answers. In other words, I'm guessing that if all-bits-zero is a
valid representation of 0.0, it's the default representation of 0.0
(for each floating-point type in each implementation).


I have seen one implementation where long double was 12 byte, with two
padding bytes.
Nov 14 '05 #27

P: n/a
CBFalconer wrote:
E. Robert Tisdale wrote:

... snip ...
But, there are no implementations of the C 89 or C99 standard
that use anything but all zero bits to represent NULL or +0.0.
Obviously you have secured and exhaustively examined
every std C implementation on any machine whatsoever.


Pretty much.
Sounds like a lot of work.
It is.
Was this funded by NASA,
Yes.
and how did you determine that you checked each and every one?
Where did you put those myriad systems?
I didn't put them anywhere.
I have access to literally thousands of machines.
Maybe we should all write NASA and ask for the report.
The exhaustive listing should be useful.
Being government funded it should be freely available.


I agree.
And, if there was a formal report that I was aware of,
I would provide you with a citation.
But I don't think that there is such a report.
This is just "common knowledge".
At least for someone who is supposed to be
some kind of expert in computer architecture and arithmetic.

I found a copy of your resume:

http://cbfalconer.home.att.net/cbf/cbfres03.txt

It says that you studied Mathematics and Physics at McGill University
but it doesn't mention a degree. Did you graduate from McGill
before going to work for the School of Medicine at Yale University
in 1974. Why did you choose to attend University in Canada
during the war in Vietnam?

I see that you've had your ups-and-downs with Otis Elevator. :-)
What is your status now?
Are you a consultant again?
Or have you retired?
Nov 14 '05 #28

P: n/a

"E. Robert Tisdale" <E.**************@jpl.nasa.gov> wrote in message
But, there are no implementations of the C 89 or C99 standard
that use anything but all zero bits to represent NULL or +0.0.

The problem is that the standard allows it. For instance, if an architecture
appeared that trapped whenever an illegal address (including 0) was loaded
into an address register, then obviously NULL would have to be some other
value. If someone invented a fast floating-point unit which relied on zero
not being all bits clear, then similarly an exception would have to be made.

The fact is that C is such a common language that most architectures are
designed with C compilers in mind, and many programs would break if NULL or
0.0 was not all bits zero. It's the problem of programs which are portable
enough for practical purposes, but not strictly compliant.
Nov 14 '05 #29

P: n/a
Trolling away again, I see.

WWKKWWWWWWKKWWWWWWKKWWWWWWKKWWKKWWWWKKWWWWKKWWWWWW WWKKWWWWKKWWWWWWWWWW
WWWWWWKKWWWWWWKKWWWWWWKKWWWWWWWWWWWWWWWWWWWWWWKKWW WWWWWWWWWWWWKKWWKKWW
WWKKWWWWKKWWWWWWWWKKWWWWWWWW.. WWWW WWWWWWKKWWKKWWKKWWWWWWWWWW
WWWWWWWWWWWWKKWWWWWWWWWW WWWWWWWWWWWWWWKKWWWWKK
WWKKWWKKWWWWWWWWKKWWWW WWWWKKWWKKWWWWWWWWWW
WWWWWWWWWWKKWWWWWW WWWWWWWWWWKKWWKKWW
WWKKWWKKWWWWKKWW WWWWKKWWWWWWWWWW
WWWWWWWWWWWWWW.. ,,::::.. WWWWWWWWKKWWWW
WWKKWWWWKKWWWW ,,iittttii,,::.. WWWWKKWWWWWWKK
WWWWWWWWWWKK ,,;;;;iittii;;,,,,,,:: ..,, WWWWKKWWWWWW
WWKKWWKKWWWW .. ::;;;;,,;;,,,,,,,,::.. :::: WWWWWWWWKKWW
WWWWWWWWWWWW ,,;;,,,,,,,,,,,,,,:: ,,.. ..KKWWWWWWWW
WWKKWWKKWW ..,,;;;;,,,,,,,,,,,,::.. ..,,,, ..WWKKWWKKWW
WWWWWWWWWW ::;;;;ii;;,,,,::,,::::::.. ::::;; WWWWWWWWWW
WWKKWWWWWW ..iiiiii;;,,,,,,::,,::,,::,,,,;;;;.. WWKKWWKKWW
WWWWWWKK ..;;iiiiii;;;;,,;;,,,,,,;;iiiiii;;.. WWWWWWWWWW
WWKKWWWW ,,;;iiiiii;;;;,,,,,,,,,,;;iiiiiiii.. WWWWKKWWWW
WWWWWWWW ::iiiiiiiiii;;;;;;,,,,,,;;;;;;;;ttii,, WWWWWWKK
WWKKWWKK ..;;;;iittLLGGttttttiiiiiiiittjjttiiiiii.. WWKKWWWW
WWWWWWWW ..;;;;iiffLLDDEEEEDDffttLLEEKKKKEELLfftt::.. WWWWWWWW
WWKKWWWW ..;;iittjjffffDDEEGGjjiiDDKKDDGGDDDDffjj;; WWKKWWWW
WWWWWWKKWW ..::;;;;iijjGGEEEEEEGGjj;;LLEEEEEEEEEELLjjii:: WWWWWWKK
WWKKWWWWWW ..,,;;;;iittiitttttttttt;;ffGGffffLLtt,,tttt:: WWWWKKWWWW
WWWWWWKKWWWW,,,,;;;;;;iiiiiiiiiitttt,,;;LLtttttt,, ;;ttLL,,WWKKWWWWWWWW
WWKKWWWWWWKKii,,;;ii;;;;,,;;,,iiii;;;;,,jjjjii;;;; ;;ttGG::WWWWWWWWKKWW
WWWWWWKKWWWWttiiiiii;;;;;;;;ttLLffttjjLLGGDDffiiii ttttLL WWKKWWWWWWWW
WWKKWWWWWWWWiiii;;;;;;ii;;ttGGLLEEEEEEKKKKDDLLjjff ffffff..WWWWWWKKWWWW
WWWWWWKKWWWWjjtt;;iiiiiittLLGGffLLLLDDEEDDDDGGLLff LLGGGG;;WWKKWWWWKKWW
WWKKWWWWKKWW;;iiiiiiiiiiffDDDDLLLLLLGGGGDDEEEEGGff GGGGGGttWWWWWWWWWWWW
WWWWWWWWWWWW,,iiiiiittttffDDEEDDEEEEGGEEKKKKEEffLL DDDDDDffKKWWKKWWKKWW
WWKKWWKKWW,,,,iittiiiittffGGttttttffLLGGGGGGLLjjLL DDEEEEttWWWWWWWWWWWW
WWWWWWWWiiiiiijjjjjjttffffffjjttjjGGGGGGLLGGLLGGDD DDEEEE;;WWWWKKWWKKWW
WWKKWWfftt;;LLjjffLLffffLLLLjjiittttjjLLffLLDDEEEE EEEEff;;iiWWWWWWWWWW
WWWWWW;;..ttEEttffLLGGGGLLLLffjjttttjjffLLDDEEKKKK KKKKLL,,ttttWWKKWWWW
WWWW::..,,ffEEffjjLLLLLLGGDDGGLLffLLLLLLDDEEKKKKKK EEKKDD,,::;;;;WWWWii
::....;;ffLLEEDDttffLLGGLLLLGGEEEEEEEEKKKKKKKKEEKK EEEEEEii;;..,,,,;;tt
.....::jjGGGGDDEEffjjffLLLLffffffGGEEEEEEEEEEKKEEK KEEKKEEfftt;;::..::tt
...::;;jjDDDDGGEEGGiijjffGGffLLLLLLGGGGDDEEKKEEKKE EKKKKDDLLjjtt;;::::..
,,,,iiiiEEDDDDDDDDttttffLLLLLLGGLLGGDDEEEEEEKKEEDD KKEEDDffjjLLGGtt,,..
,,;;ttffDDEEDDDDEELLttjjLLLLLLGGLLDDEEEEEEEEEEDDDD KKDDLLffGGEEEEtt,,::
,,;;iiGGGGEEKKEEEEDDjjttffffLLLLDDGGDDDDEEGGDDDDEE GGLLjjDDEEKKLLii,,,,
;;iiiiLLEEDDEEEEDDDDffffffjjffLLGGGGDDGGLLGGGGDDLL GGLLEEEEKKGGjjii;;;;
iiiittttLLEEEEEEKKKKjjttffffjjffffffjjffffLLDD;;GG KKKKKKEEDDffttii;;;;
iiiiiittffLLGGDDEEKKDDffffffjjjjttttiittffjjiittKK KKEEEEGGLLttiiii;;;;
iiiittiiffffjjffjjLLDDEEDDLLttjjjjjjttjjttffKKKKDD GGGGLLLLttttiiii;;;;
iiiiiittttjjffjjffffffLLDDEEEELLffffjjttDDKKKKDDGG GGffffffttiiii;;;;ii
iiiiiittttttjjjjjjjjffffffLLLLGGDDffffEEEEDDGGGGLL LLffjjttiiii;;iiiiii
--
Sev
Nov 14 '05 #30

P: n/a
"Malcolm" <ma*****@55bank.freeserve.co.uk> writes:
"E. Robert Tisdale" <E.**************@jpl.nasa.gov> wrote in message
But, there are no implementations of the C 89 or C99 standard
that use anything but all zero bits to represent NULL or +0.0.

The problem is that the standard allows it. For instance, if an architecture
appeared that trapped whenever an illegal address (including 0) was loaded
into an address register, then obviously NULL would have to be some other
value.

[...]

Maybe not. I think the only operation for which it matters is
equality comparison. If the compiler doesn't load a pointer value
into an address register for a pointer comparison, it might still be
able to use all-bits-zero for null pointers.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #31

P: n/a
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.org> wrote:
Maybe not. I think the only operation for which it matters is
equality comparison. If the compiler doesn't load a pointer value
into an address register for a pointer comparison, it might still be
able to use all-bits-zero for null pointers.


Surely it would have to ensure that it never loaded a pointer that
might be null into a register? Even, say, when assigning a
possibly-null pointer to a variable, or passing it to a procedure.
This would be possible on architectures with memory-to-memory move
instructions and which passed all arguments on the stack, but probably
inefficient.

-- Richard
Nov 14 '05 #32

P: n/a
ri*****@cogsci.ed.ac.uk (Richard Tobin) writes:
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.org> wrote:
Maybe not. I think the only operation for which it matters is
equality comparison. If the compiler doesn't load a pointer value
into an address register for a pointer comparison, it might still be
able to use all-bits-zero for null pointers.


Surely it would have to ensure that it never loaded a pointer that
might be null into a register? Even, say, when assigning a
possibly-null pointer to a variable, or passing it to a procedure.
This would be possible on architectures with memory-to-memory move
instructions and which passed all arguments on the stack, but probably
inefficient.


Assignment and argument passing are also an issue of course; thanks
for reminding me.

Note that we're talking specifically about address registers; data
registers might be separate. (The 68k has separate data and address
registers, though it doesn't do the trap-on-loading-NULL thing.)

For equality comparison, assignment, or argument passing, it doesn't
matter whether a value is an address or an integer of equal size
(assuming there aren't multiple representations for the same address),
so those operations could be done using data registers. Relational
operators ("<", "<=", ">", ">=") might or might not require an address
register; applying such an operator to NULL invokes undefined behavior
anyway. The only time you really need to use an address register is
if you're going to dereference the pointer; in that case, trapping on
NULL is a good thing.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #33

P: n/a
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
ri*****@cogsci.ed.ac.uk (Richard Tobin) writes:
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.org> wrote:
Maybe not. I think the only operation for which it matters is
equality comparison. If the compiler doesn't load a pointer value
into an address register for a pointer comparison, it might still be
able to use all-bits-zero for null pointers.


Surely it would have to ensure that it never loaded a pointer that
might be null into a register? Even, say, when assigning a
possibly-null pointer to a variable, or passing it to a procedure.
This would be possible on architectures with memory-to-memory move
instructions and which passed all arguments on the stack, but probably
inefficient.


Assignment and argument passing are also an issue of course; thanks
for reminding me.

Note that we're talking specifically about address registers; data
registers might be separate. (The 68k has separate data and address
registers, though it doesn't do the trap-on-loading-NULL thing.)

For equality comparison, assignment, or argument passing, it doesn't
matter whether a value is an address or an integer of equal size
(assuming there aren't multiple representations for the same address),
so those operations could be done using data registers. Relational
operators ("<", "<=", ">", ">=") might or might not require an address
register; applying such an operator to NULL invokes undefined behavior
anyway. The only time you really need to use an address register is
if you're going to dereference the pointer; in that case, trapping on
NULL is a good thing.


The IBM z/Architecture mainframe is 64-bit addresses. General
purpose registers are used for holding addresses. There is no
trap-on-bad-address-loaded-into-register thing. Location zero
is a valid address, and location 0x80000000 is never valid for
virtual addresses when running the z/OS operating system. Attempting
to dereference 0x80000000 will cause a hardware exception trap.

Therefore, a conforming compiler can translate NULL in the
source code into 0x80000000 for the run-time object code,
and then translate 0x80000000 at run-time to mean NULL. I do
not know of any conforming compilers that do this for z/Arch;
they all use zero for both NULL and the run-time bitwise
representation of NULL, and they expect the programmer to know
what he is doing.
--
----------------------------
Jeffrey D. Smith
Farsight Systems Corporation
24 BURLINGTON DRIVE
LONGMONT, CO 80501-6906
http://www.farsight-systems.com
z/Debug debugs your Systems/C programs running on IBM z/OS for FREE!
Nov 14 '05 #34

P: n/a
In <ch*********************************@slb-newsm1.svr.pol.co.uk> Christian Bau <ch***********@cbau.freeserve.co.uk> writes:
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.org> wrote:
Just to add to the confusion, there are really two different questions
here. One, the issue raised by the OP, is whether using memset to
assign all-bits-zero to a floating-point object will result in a value
equal to 0.0. The other is whether assigning the value 0.0 to a
floating-point object will result in the object containing
all-bits-zero.

The possible existence of multiple representations for 0.0 means that
these are not the same question. However, I'd be very surprised if
there were an implementation for which these questions have different
answers. In other words, I'm guessing that if all-bits-zero is a
valid representation of 0.0, it's the default representation of 0.0
(for each floating-point type in each implementation).


I have seen one implementation where long double was 12 byte, with two
padding bytes.


That's quite common nowadays on x86 compilers, due to alignment issues.
E.g. gcc and the Intel C compiler on x86. The other common option for
x86 implementations is 8 bytes (the same as double).

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #35

P: n/a
In <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
"Malcolm" <ma*****@55bank.freeserve.co.uk> writes:
"E. Robert Tisdale" <E.**************@jpl.nasa.gov> wrote in message
> But, there are no implementations of the C 89 or C99 standard
> that use anything but all zero bits to represent NULL or +0.0.
>

The problem is that the standard allows it. For instance, if an architecture
appeared that trapped whenever an illegal address (including 0) was loaded
into an address register, then obviously NULL would have to be some other
value.

[...]

Maybe not. I think the only operation for which it matters is
equality comparison. If the compiler doesn't load a pointer value
into an address register for a pointer comparison, it might still be
able to use all-bits-zero for null pointers.


OTOH, if the CPU has dedicated address registers, it may be that ALL
pointer operations are more efficient if using address registers.

Think about a CPU with 32-bit data registers and 48-bit address registers.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #36

P: n/a
Da*****@cern.ch (Dan Pop) writes:
In <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
"Malcolm" <ma*****@55bank.freeserve.co.uk> writes:
"E. Robert Tisdale" <E.**************@jpl.nasa.gov> wrote in message
> But, there are no implementations of the C 89 or C99 standard
> that use anything but all zero bits to represent NULL or +0.0.
>
The problem is that the standard allows it. For instance, if an
architecture appeared that trapped whenever an illegal address
(including 0) was loaded into an address register, then obviously
NULL would have to be some other value.

[...]

Maybe not. I think the only operation for which it matters is
equality comparison. If the compiler doesn't load a pointer value
into an address register for a pointer comparison, it might still be
able to use all-bits-zero for null pointers.


OTOH, if the CPU has dedicated address registers, it may be that ALL
pointer operations are more efficient if using address registers.

Think about a CPU with 32-bit data registers and 48-bit address registers.


On any CPU, the code generated by a C compiler has to be able to do
assignments and equality comparisons on pointer values, including null
pointer values. If loading a null pointer into an address register
causes a trap, the C implementation won't be able to use the address
registers for pointer assignment and equality comparison (unless it
can recover in the trap handler, but that's likely to be inefficient).

If it's possible to perform these operations efficiently without using
the address registers, that's great; a C compiler will be able to use
all-bit-zero as the null pointer value, and everything will work. If
it isn't, either the C compiler will be forced to use a different
value for null pointers, or it won't be possible to implement C
efficiently. The same will probably be true for languages other than
C, which probably means that no such CPU will be designed for
general-purpose computers.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #37

P: n/a
In <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
Da*****@cern.ch (Dan Pop) writes:
In <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
>"Malcolm" <ma*****@55bank.freeserve.co.uk> writes:
>> "E. Robert Tisdale" <E.**************@jpl.nasa.gov> wrote in message
>> > But, there are no implementations of the C 89 or C99 standard
>> > that use anything but all zero bits to represent NULL or +0.0.
>> >
>> The problem is that the standard allows it. For instance, if an
>> architecture appeared that trapped whenever an illegal address
>> (including 0) was loaded into an address register, then obviously
>> NULL would have to be some other value.
>[...]
>
>Maybe not. I think the only operation for which it matters is
>equality comparison. If the compiler doesn't load a pointer value
>into an address register for a pointer comparison, it might still be
>able to use all-bits-zero for null pointers.
OTOH, if the CPU has dedicated address registers, it may be that ALL
pointer operations are more efficient if using address registers.

Think about a CPU with 32-bit data registers and 48-bit address registers.


On any CPU, the code generated by a C compiler has to be able to do
assignments and equality comparisons on pointer values, including null
pointer values. If loading a null pointer into an address register
causes a trap, the C implementation won't be able to use the address
registers for pointer assignment and equality comparison (unless it
can recover in the trap handler, but that's likely to be inefficient).


But there is nothing preventing the implementor to use a null pointer
representation that doesn't trap! Even if that representation is not
all bits zero.
If it's possible to perform these operations efficiently without using
the address registers, that's great;
Even then, why bother? If address registers exist in the first place,
there *must* be a reason. Not using them for pointer operation is very
likely to be inefficient, even if they have the same size as data
registers for the simple reason that data registers get under greater
pressure, while the address registers are unused. When the sizes are
different, as in my example, the difference is going to be even more
important.
a C compiler will be able to use
all-bit-zero as the null pointer value, and everything will work.
You make it sound as if there is any merit in having null pointers
represented as all bits zero. Why would the implementor try to use
that representation, if it's causing even the slightest inconvenience?
If it isn't, either the C compiler will be forced to use a different
value for null pointers,
The representation of null pointers is supposed to be the most convenient
and efficient for the implementation, so there is no reason to consider
all bits zero as an a priori solution, unless it is a convenient choice.
or it won't be possible to implement C efficiently.
Only an idiot would create an inefficient implementation for the sake of
having null pointers represented as all bits zero. See below.
The same will probably be true for languages other than
C, which probably means that no such CPU will be designed for
general-purpose computers.


Sheer nonsense. There is always an efficient solution: create a
"reserved" object at some address and use its address as the null pointer
representation. This is what most implementations are doing anyway, using
the address 0 for this purpose. But there is nothing magic about this
address, it just happens to be very convenient for this particular
purpose, on most architectures.

Since most modern machines treat addresses as unsigned integers,
address 0 happens to be at the beginning of the address space and it's
traditionally reserved anyway, on non-virtual memory architectures:
it's the address of a GPR or an interrupt vector or the entry point in
the boot loader (possibly ROM space). On virtual memory architectures,
it's simply a matter of either leaving page zero unmapped (best choice,
IMHO) or mapping but not using it (in read only mode, preferably).

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #38

P: n/a
This is generating a lot more discussion than it deserves.

Malcolm speculated upthread that on a hypothetical CPU that traps on
an attempt to load an illegal address, including all-bits-zero, into
an address register, a C implementation would have to use a
non-all-bits-zero value for the null pointer. I replied that, given a
couple of additional assumptions about the architecture, it still
could, and arguably should, use all-bits-zero for the null pointer.

More concretely, assume something similar to the 68k, with its
separate data and address registers, all the same size (32 bits, or
whatever). Assume that, unlike the 68k, loading any invalid address,
including all-bits-zero, into an address register causes a trap, and
that handling a trap is relatively expensive. Finally, assume that an
address is effectively an unsigned integer representing an index into
the (32-bit?) address space. On such an architecture, a C
implementation could reasonably use all-bits-zero as the null pointer
representation. Pointer assignment and equality comparison would use
the data registers, not the address registers, so they'll work
properly with null pointer values. Deferencing a pointer requires
loading its value into an address register, causing a trap if it's
invalid -- which is exactly what we want. Pointer arithmetic probably
uses the data registers as well, but if some operations are easier
using the address registers, the trap on a null pointer is again
exactly what we want. (It's undefined behavior, but I'd rather see it
blow up immediately than fail silently and cause further havoc later
on.)

[...]
But there is nothing preventing the implementor to use a null pointer
representation that doesn't trap! Even if that representation is not
all bits zero.


On the hypothetical CPU I describe above, there is nothing preventing
the implementor to use a null pointer that *does* trap.
If it's possible to perform these operations efficiently without using
the address registers, that's great;


Even then, why bother? If address registers exist in the first place,
there *must* be a reason. Not using them for pointer operation is very
likely to be inefficient, even if they have the same size as data
registers for the simple reason that data registers get under greater
pressure, while the address registers are unused. When the sizes are
different, as in my example, the difference is going to be even more
important.


If using a value other than all-bits-zero for null pointers makes it
possible to generate more efficient code, then by all means do so. I
suggested that using all-bits-zero for null pointers is possible; I
never suggested doing so if it's less efficient.
a C compiler will be able to use
all-bit-zero as the null pointer value, and everything will work.


You make it sound as if there is any merit in having null pointers
represented as all bits zero. Why would the implementor try to use
that representation, if it's causing even the slightest inconvenience?


I said it's possible to use all-bits-zero as the null pointer, not
that there's any great merit in doing so. Now that I think about it,
though, there is some merit in not breaking badly written code that
assumes the null pointer is all-bits-zero. There is also some merit
in breaking such code so it can be corrected. But the vast majority
of C implementors, for whatever reason, have chosen to use
all-bits-zero as the null pointer, and they're likely to continue to
do so if there's no significant cost.

[...]
The same will probably be true for languages other than
C, which probably means that no such CPU will be designed for
general-purpose computers.


Sheer nonsense. There is always an efficient solution: create a
"reserved" object at some address and use its address as the null pointer
representation. This is what most implementations are doing anyway, using
the address 0 for this purpose. But there is nothing magic about this
address, it just happens to be very convenient for this particular
purpose, on most architectures.


And if an attempt to dereference this address causes a trap, that's an
advantage, not a disadvantage. If you're not going to deference it,
don't load it into an address register.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #39

P: n/a
Keith Thompson <ks***@mib.org> wrote:
This is generating a lot more discussion than it deserves.

Malcolm speculated upthread that on a hypothetical CPU that traps on
an attempt to load an illegal address, including all-bits-zero, into
an address register, a C implementation would have to use a
non-all-bits-zero value for the null pointer. I replied that, given a
couple of additional assumptions about the architecture, it still
could, and arguably should, use all-bits-zero for the null pointer.
I've seen you state that it could (and I agree), but I haven't seen you
arguing that it should. And IMO you'd need some pretty good arguments,
because sacrificing speed and safety just to cater for sloppy
programmers is rarely a good idea, IYAM.
Assume that, unlike the 68k, loading any invalid address,
including all-bits-zero, into an address register causes a trap, and
that handling a trap is relatively expensive. On such an architecture, a C
implementation could reasonably use all-bits-zero as the null pointer
representation. Pointer assignment and equality comparison would use
the data registers, not the address registers, so they'll work
properly with null pointer values.
So does passing pointers to functions. Not nice, IMO.
I said it's possible to use all-bits-zero as the null pointer, not
that there's any great merit in doing so. Now that I think about it,
though, there is some merit in not breaking badly written code that
assumes the null pointer is all-bits-zero.


IMAO, there is no merit in it at all. Such code is broken, and always
will be broken. It is better to correct its programmers than to
discorrect the compiler.

Richard
Nov 14 '05 #40

P: n/a
In <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
This is generating a lot more discussion than it deserves.


And it is entirely due to your pointless remarks.

If all bits zero is an inconvenient representation for the null pointer on
a given platform, no implementor is going to use it and there is no point
in explaining how it could be used, anyway.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #41

P: n/a
rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
Keith Thompson <ks***@mib.org> wrote:
This is generating a lot more discussion than it deserves.

Malcolm speculated upthread that on a hypothetical CPU that traps on
an attempt to load an illegal address, including all-bits-zero, into
an address register, a C implementation would have to use a
non-all-bits-zero value for the null pointer. I replied that, given a
couple of additional assumptions about the architecture, it still
could, and arguably should, use all-bits-zero for the null pointer.


I've seen you state that it could (and I agree), but I haven't seen you
arguing that it should. And IMO you'd need some pretty good arguments,
because sacrificing speed and safety just to cater for sloppy
programmers is rarely a good idea, IYAM.


My assumption was that there would be no performance penalty in using
data registers for any operations that are valid for null pointers.
And catering to sloppy programmers, unfortunately, can be an effective
way to sell more compilers.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #42

P: n/a
Da*****@cern.ch (Dan Pop) writes:
In <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
This is generating a lot more discussion than it deserves.
And it is entirely due to your pointless remarks.


Nonsense. I was merely responding to Malcolm's remarks about a
hypothetical architecture. He said that on a CPU where loading
all-bits-zero into an address register causes a trap, a C
implementation would have to use some other value for null pointers.
I pointed out that, given a few additional assumptions, an
implementation *could* use all-bits-zero for null pointers, and there
are some advantages in doing so. One is that it makes it easy to trap
attempts to dereference null pointers. Another is that it avoids
breaking existing code that incorrectly assumes a null pointer is
all-bits-zero. (You and I might consider this second point to be a
disadvantage, but the sales and marketing departments might differ.)

BTW, none of this is intended as a criticism of Malcom; it was nothing
more than a friendly correction.

The length of this thread is due to your apparent need to jump in and
refute your misinterpretation of what I actually wrote.
If all bits zero is an inconvenient representation for the null pointer on
a given platform, no implementor is going to use it and there is no point
in explaining how it could be used, anyway.


I'm not convinced of that. There's still a lot of code out there that
passes null pointers to functions without prototypes, and that will
break if null pointers are anything other than all-bits-zero. An
implementer is faced with a choice: use a non-zero value, causing such
code to break (and, we might hope, be fixed), or cater to it and very
likely sell more compilers to users who don't have time to go back and
fix their old code. I'm not necessarily arguing that the second
choice is a good one, but it's one that some implementers might be
likely to make.

But that's really beside the point I was trying to make, which is that
trapping on loading all-bits-zero into an address register doesn't
necessarily make all-bits-zero an inconvenient representation for the
null pointer.

On a typical platform, all-bits-zero and all-bits-one are equally
valid choices for the null pointer. Any compiler implementer could
easily choose to use the latter. (It's not an option if there are
existing libraries that use all-bits-zero, but presumably the choice
is available for new architectures.) And yet, every system I'm
familiar with uses all-bits-zero for null pointers. (Yes, I know
there are a lot of systems I'm not familiar with.) I'm sure a lot of
that is inertia, but I would guess that catering to existing broken
code is part of the motivation for that.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #43

P: n/a
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.org> wrote:
I'm not convinced of that. There's still a lot of code out there that
passes null pointers to functions without prototypes, and that will
break if null pointers are anything other than all-bits-zero.
That kind of code would also break if arguments are passed on the stack,
and int and pointers have different sizes.
An
implementer is faced with a choice: use a non-zero value, causing such
code to break (and, we might hope, be fixed), or cater to it and very
likely sell more compilers to users who don't have time to go back and
fix their old code. I'm not necessarily arguing that the second
choice is a good one, but it's one that some implementers might be
likely to make.

But that's really beside the point I was trying to make, which is that
trapping on loading all-bits-zero into an address register doesn't
necessarily make all-bits-zero an inconvenient representation for the
null pointer.

On a typical platform, all-bits-zero and all-bits-one are equally
valid choices for the null pointer. Any compiler implementer could
easily choose to use the latter. (It's not an option if there are
existing libraries that use all-bits-zero, but presumably the choice
is available for new architectures.) And yet, every system I'm
familiar with uses all-bits-zero for null pointers. (Yes, I know
there are a lot of systems I'm not familiar with.) I'm sure a lot of
that is inertia, but I would guess that catering to existing broken
code is part of the motivation for that.

Nov 14 '05 #44

P: n/a
Keith Thompson <ks***@mib.org> wrote:
rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
Keith Thompson <ks***@mib.org> wrote:
I replied that, given a
couple of additional assumptions about the architecture, it still
could, and arguably should, use all-bits-zero for the null pointer.
I've seen you state that it could (and I agree), but I haven't seen you
arguing that it should. And IMO you'd need some pretty good arguments,
because sacrificing speed and safety just to cater for sloppy
programmers is rarely a good idea, IYAM.


My assumption was that there would be no performance penalty in using
data registers for any operations that are valid for null pointers.


That is, data registers must be used for every possible operation except
dereferencing and comparison for order (there's no exception for
equality comparisons!), if there is even a small chance of any operand
being a null pointer. I don't think that such an architecture is likely
to even have pointer registers - under those constraints, they're nearly
useless.
And catering to sloppy programmers, unfortunately, can be an effective
way to sell more compilers.


Ah, well, that's the difference between "should" and "will have to".
Unfortunately.

Richard
Nov 14 '05 #45

P: n/a
In article <40****************@news.individual.net>,
rl*@hoekstra-uitgeverij.nl (Richard Bos) wrote:
Keith Thompson <ks***@mib.org> wrote:
rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
Keith Thompson <ks***@mib.org> wrote:
> I replied that, given a
> couple of additional assumptions about the architecture, it still
> could, and arguably should, use all-bits-zero for the null pointer.

I've seen you state that it could (and I agree), but I haven't seen you
arguing that it should. And IMO you'd need some pretty good arguments,
because sacrificing speed and safety just to cater for sloppy
programmers is rarely a good idea, IYAM.


My assumption was that there would be no performance penalty in using
data registers for any operations that are valid for null pointers.


That is, data registers must be used for every possible operation except
dereferencing and comparison for order (there's no exception for
equality comparisons!), if there is even a small chance of any operand
being a null pointer. I don't think that such an architecture is likely
to even have pointer registers - under those constraints, they're nearly
useless.


Address registers could be used for any kind of pointer arithmetic,
which I think is quite common. And of course you could use the address
registers for anything if you can prove that a null pointer will lead to
undefined behavior somewhere along the line; I think that will be quite
common as well.
Nov 14 '05 #46

P: n/a
In <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
Da*****@cern.ch (Dan Pop) writes:

The length of this thread is due to your apparent need to jump in and
refute your misinterpretation of what I actually wrote.
Since I wasn't the only one to "misinterpret" what you wrote, the guilty
party must be searched somewhere else.
If all bits zero is an inconvenient representation for the null pointer on
a given platform, no implementor is going to use it and there is no point
in explaining how it could be used, anyway.


I'm not convinced of that. There's still a lot of code out there that
passes null pointers to functions without prototypes, and that will
break if null pointers are anything other than all-bits-zero.


You're badly confusing null pointers and the null pointer constant.
There is absolutely nothing wrong with passing a null pointer to a
non-prototyped function, regardless of the representation of the null
pointer.

Passing 0 to a non-prototyped function expecting a pointer is and has
*always* been an error. Read the standard. Read K&R1.
But that's really beside the point I was trying to make, which is that
trapping on loading all-bits-zero into an address register doesn't
necessarily make all-bits-zero an inconvenient representation for the
null pointer.


It does, every time address registers have different properties than
data registers. And even otherwise, as it puts a greater pressure on
the data registers. If the architecture has address registers, there
must be a *good* reason for that and using data registers instead for
pointer operations is defeating that good reason.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #47

P: n/a
Da*****@cern.ch (Dan Pop) writes:
In <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
Da*****@cern.ch (Dan Pop) writes: [snip]
If all bits zero is an inconvenient representation for the null pointer on
a given platform, no implementor is going to use it and there is no point
in explaining how it could be used, anyway.


I'm not convinced of that. There's still a lot of code out there that
passes null pointers to functions without prototypes, and that will
break if null pointers are anything other than all-bits-zero.


You're badly confusing null pointers and the null pointer constant.
There is absolutely nothing wrong with passing a null pointer to a
non-prototyped function, regardless of the representation of the null
pointer.

Passing 0 to a non-prototyped function expecting a pointer is and has
*always* been an error. Read the standard. Read K&R1.


Yes, I meant null pointer constants. I didn't badly confuse them; I
made a minor error.

Yes, passing 0 (or NULL, if it's #defined as 0) to a non-prototyped
function expecting a pointer is an error. The fact remains that there
is code in the real world that makes this error, and happens to work
as expected on platforms where pointers are the same size as int and
the null pointer has the same representation as (int)0.

Dan, did you really think that I don't know already this? I've
written enough here about null pointers and null pointer constants
that it should be pretty obvious that I do understand this stuff
reasonably well. If I type "null pointers" when "null pointer
constants" would make more sense, a reasonable reader would assume I
made a minor mistake, not that I have no idea what I'm talking about.
But that's really beside the point I was trying to make, which is that
trapping on loading all-bits-zero into an address register doesn't
necessarily make all-bits-zero an inconvenient representation for the
null pointer.


It does, every time address registers have different properties than
data registers. And even otherwise, as it puts a greater pressure on
the data registers. If the architecture has address registers, there
must be a *good* reason for that and using data registers instead for
pointer operations is defeating that good reason.


I didn't think about the hypothetical CPU architecture to that level
of detail, because I was only trying to make a minor point about
what's possible.

I don't currently have convenient access to 68k machine code, but the
68k does have separate data and address registers. If I recall
correctly (which I might not), adding a value other than 1, 2, or 4 to
an address requires loading it into a data register and performing
integer arithmetic on it (adding 1, 2, or 4 can be done with
auto-increment addressing modes). There may even be cases where it
makes sense to use address registers for some operations on integers.

Not all CPU architectures are flawless. Once the architecture is
fixed, I would expect a compiler to do whatever is most convenient
and/or efficient, even if it means using data registers for address
operations or vice versa.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #48

P: n/a
In <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
Da*****@cern.ch (Dan Pop) writes:
In <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
>Da*****@cern.ch (Dan Pop) writes:[snip] >> If all bits zero is an inconvenient representation for the null pointer on
>> a given platform, no implementor is going to use it and there is no point
>> in explaining how it could be used, anyway.
>
>I'm not convinced of that. There's still a lot of code out there that
>passes null pointers to functions without prototypes, and that will
>break if null pointers are anything other than all-bits-zero.
You're badly confusing null pointers and the null pointer constant.
There is absolutely nothing wrong with passing a null pointer to a
non-prototyped function, regardless of the representation of the null
pointer.

Passing 0 to a non-prototyped function expecting a pointer is and has
*always* been an error. Read the standard. Read K&R1.


Yes, I meant null pointer constants. I didn't badly confuse them; I
made a minor error.

Yes, passing 0 (or NULL, if it's #defined as 0) to a non-prototyped
function expecting a pointer is an error. The fact remains that there
is code in the real world that makes this error, and happens to work
as expected on platforms where pointers are the same size as int and
the null pointer has the same representation as (int)0.


This is not enough to make it work. If the platform has separate data
and address registers, the value *may* be passed in the "wrong" register
and the code will fail miserably.
Dan, did you really think that I don't know already this? I've


I have no clue about what you know and what you don't, especially
since there are many technical inaccuracies in your posts, as the
ones pointed out above. It's none of my business to figure out what you
know or what you mean, when what you write is downright incorrect.

I don't know why you keep invoking severely broken code that happens to
work by accident as an argument. Please show us some *concrete* evidence
that implementors care about such code when making their decisions and
that they're ready to sacrifice performance in order to keep broken code
working as intended by its developer.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #49

P: n/a


Dan Pop wrote:
In <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
Da*****@cern.ch (Dan Pop) writes:
In <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
>"Malcolm" <ma*****@55bank.freeserve.co.uk> writes:
>> "E. Robert Tisdale" <E.**************@jpl.nasa.gov> wrote in message
>> > But, there are no implementations of the C 89 or C99 standard
>> > that use anything but all zero bits to represent NULL or +0.0.
>> >
>> The problem is that the standard allows it. For instance, if an
>> architecture appeared that trapped whenever an illegal address
>> (including 0) was loaded into an address register, then obviously
>> NULL would have to be some other value.
>[...]
>
>Maybe not. I think the only operation for which it matters is
>equality comparison. If the compiler doesn't load a pointer value
>into an address register for a pointer comparison, it might still be
>able to use all-bits-zero for null pointers.

OTOH, if the CPU has dedicated address registers, it may be that ALL
pointer operations are more efficient if using address registers.

Think about a CPU with 32-bit data registers and 48-bit address registers.


On any CPU, the code generated by a C compiler has to be able to do
assignments and equality comparisons on pointer values, including null
pointer values. If loading a null pointer into an address register
causes a trap, the C implementation won't be able to use the address
registers for pointer assignment and equality comparison (unless it
can recover in the trap handler, but that's likely to be inefficient).


But there is nothing preventing the implementor to use a null pointer
representation that doesn't trap! Even if that representation is not
all bits zero.
If it's possible to perform these operations efficiently without using
the address registers, that's great;


Even then, why bother? If address registers exist in the first place,
there *must* be a reason. Not using them for pointer operation is very
likely to be inefficient, even if they have the same size as data
registers for the simple reason that data registers get under greater
pressure, while the address registers are unused. When the sizes are
different, as in my example, the difference is going to be even more
important.
a C compiler will be able to use
all-bit-zero as the null pointer value, and everything will work.


You make it sound as if there is any merit in having null pointers
represented as all bits zero. Why would the implementor try to use
that representation, if it's causing even the slightest inconvenience?
If it isn't, either the C compiler will be forced to use a different
value for null pointers,


The representation of null pointers is supposed to be the most convenient
and efficient for the implementation, so there is no reason to consider
all bits zero as an a priori solution, unless it is a convenient choice.
or it won't be possible to implement C efficiently.


Only an idiot would create an inefficient implementation for the sake of
having null pointers represented as all bits zero. See below.
The same will probably be true for languages other than
C, which probably means that no such CPU will be designed for
general-purpose computers.


Sheer nonsense. There is always an efficient solution: create a
"reserved" object at some address and use its address as the null pointer
representation. This is what most implementations are doing anyway, using
the address 0 for this purpose. But there is nothing magic about this
address, it just happens to be very convenient for this particular
purpose, on most architectures.

Since most modern machines treat addresses as unsigned integers,
address 0 happens to be at the beginning of the address space and it's
traditionally reserved anyway, on non-virtual memory architectures:
it's the address of a GPR or an interrupt vector or the entry point in
the boot loader (possibly ROM space). On virtual memory architectures,
it's simply a matter of either leaving page zero unmapped (best choice,
IMHO) or mapping but not using it (in read only mode, preferably).


Or people could look at the c faq to see how this has been done in the past. At
symbolics we had a tagged architecture to handle this situation. If you are
using a theoretical system, you might as well add tags to it! BTW, this is not a
slam on anyone.

Wayne

Nov 14 '05 #50

53 Replies

This discussion thread is closed

Replies have been disabled for this discussion.