February 03, 2004
Walter wrote:
| "Matthew" <matthew.hat@stlsoft.dot.org> wrote in message
| news:bvmvui$643$1@digitaldaemon.com...
|| NaN seems arbitrarily inconsistent.
|
| That's only because there is no NaN value for integers. null is the
| NaN value for pointers and references, and that is used, too. Even
| better would be if the CPU offered some way to tag a location as
| 'empty', but so far, this does not exist outside of the 8087
| registers.

So use something like 0x80000000 or 0xdeadbeef or just about any random-looking but consistent garbage or repetitive pattern that sticks out like a sore thumb in the memory dump, preferrably large, ugly, and odd, with the hi bit set, and drop all pretense of initializing to something useful. For that matter may as well assign pointers to something evil like 0xcdcdcdcd as well, instead of null which is probably what people want... can't have that.

|| I agree that one will much more often want to rely on it being 0
|| than NaN.
|
| The point is to provide a useless value so 'uninitialized' variable
| problems will be exposed, and a consistent value to aid in tracking
| the problem down.
|
|| Is the rationale for NaN documented anywhere? I'd like to read it.

The archives of this NG have hundreds of messages, I'm sure.

| The idea is if you want to use it, you should set it to a value | first. The NaN is to catch paths where you used it but failed to | initialize it.

The general consensus seems to be that catching errors of this sort at compile time is infinitely better than relying on time spent in the debugger to find them.  I would rather the compiler be a bit of a pain in the ass than have it pretend to coddle me while actually laying landmines about in the dark for the program to trip on later.

Sean


February 03, 2004
> > NaN seems arbitrarily inconsistent.
>
> That's only because there is no NaN value for integers.

Sure, but if consistency is what you're after, why choose 0 for integers? Why not -1?

Using 0 for integers merely leads us to the current mindset whereby the expectation is the all variables are initialised to their "zero value", rather than their "null value".

> null is the NaN
> value for pointers and references, and that is used, too.

Here's the way it looks to me:

1. Pointers/references
    do not have a "zero value"
    "null value" is null

2. Integers
    "zero value" is 0
    "null value" is 0

3. Floating point
    "zero value" is 0 (or 0.0, if you like)
    "null value" is NaN

Since pointers/references do not have a "zero value", but their "null value" is what one would choose to be if "zero value" had meaning to pointers/references, I think there's a strong argument that floating point's should be default initialised to their "zero value" rather than their "null value" simply because that is what everyone will expect.

> Even better would
> be if the CPU offered some way to tag a location as 'empty', but so far,
> this does not exist outside of the 8087 registers.


I completely agree, and if integers had a well-known "null value" then this argument would be moot.

Indeed, maybe we should decide that top-bit-set is the null value,
e.g. -128, -32768, etc ? I know this sounds silly, but it is consistent with
NaN. The reason it sounds silly is that we all know that 0 is the "null
value" of integers. Alas, this knowing is what causes us all to believe that
0.0 is the "null value" of floating points, which I grant you it's not.

>
> > I agree that one will much more often want to rely on it being 0 than
NaN.
>
> The point is to provide a useless value so 'uninitialized' variable
problems
> will be exposed, and a consistent value to aid in tracking the problem
down.
>
> > Is the rationale for NaN documented anywhere? I'd like to read it.
>
> The idea is if you want to use it, you should set it to a value first. The NaN is to catch paths where you used it but failed to initialize it.

I understand that this is the intention, but since integers do not have a "null value", and integer programming is far more common that floating point, people will come to believe that all variables are zero-initialised, rather than null-initialised. I think this will cause more problems than it is intended to solve. Since everyone will always "know" that zero-initialisation is happening, the issue of whether one might forget to initialise it is moot: therefore there's no need for NaN.

And wouldn't it just be better for the compiler to tell you at compile-time that you've not initialised something, rather than you having potentially huge amounts of effort in tracing/debugging back to find that a variable started life as NaN instead of 0.0 ?



February 03, 2004
J C Calvarese wrote:
> http://www.digitalmars.com/d/property.html
> 
> It says it twice if you look hard enough...
Thanx, I didn't realized, that it is a property.

Olaf
-- 
+-------------------------------------------------------------------+ I Dr. rer. nat. Olaf Rogalsky     Institut fuer Theoretische Physik I I                                 Universitaet Erlangen-Nuernberg   I I Tel.: 09131 8528440             Staudtstr. 7 B3                   I I Fax.: 09131 8528444             D-91058 Erlangen                  I | rogalsky@theorie1.physik.uni-erlangen.de                          I +-------------------------------------------------------------------+
February 03, 2004
"Matthew" <matthew.hat@stlsoft.dot.org> wrote in message news:bvo60s$2nur$1@digitaldaemon.com...
> > > NaN seems arbitrarily inconsistent.
> >
> > That's only because there is no NaN value for integers.
>
> Sure, but if consistency is what you're after, why choose 0 for integers? Why not -1?

Consistency is not possible because there is no NaN value for integers. So we just do the best we can.

>
> Using 0 for integers merely leads us to the current mindset whereby the expectation is the all variables are initialised to their "zero value", rather than their "null value".
>
> > null is the NaN
> > value for pointers and references, and that is used, too.
>
> Here's the way it looks to me:
>
> 1. Pointers/references
>     do not have a "zero value"
>     "null value" is null
>
> 2. Integers
>     "zero value" is 0
>     "null value" is 0
>
> 3. Floating point
>     "zero value" is 0 (or 0.0, if you like)
>     "null value" is NaN
>
> Since pointers/references do not have a "zero value", but their "null
value"
> is what one would choose to be if "zero value" had meaning to pointers/references, I think there's a strong argument that floating
point's
> should be default initialised to their "zero value" rather than their
"null
> value" simply because that is what everyone will expect.
>
> > Even better would
> > be if the CPU offered some way to tag a location as 'empty', but so far,
> > this does not exist outside of the 8087 registers.
>
>
> I completely agree, and if integers had a well-known "null value" then
this
> argument would be moot.
>
> Indeed, maybe we should decide that top-bit-set is the null value, e.g. -128, -32768, etc ? I know this sounds silly, but it is consistent
with
> NaN. The reason it sounds silly is that we all know that 0 is the "null value" of integers. Alas, this knowing is what causes us all to believe
that
> 0.0 is the "null value" of floating points, which I grant you it's not.
>
> >
> > > I agree that one will much more often want to rely on it being 0 than
> NaN.
> >
> > The point is to provide a useless value so 'uninitialized' variable
> problems
> > will be exposed, and a consistent value to aid in tracking the problem
> down.
> >
> > > Is the rationale for NaN documented anywhere? I'd like to read it.
> >
> > The idea is if you want to use it, you should set it to a value first.
The
> > NaN is to catch paths where you used it but failed to initialize it.
>
> I understand that this is the intention, but since integers do not have a "null value", and integer programming is far more common that floating point, people will come to believe that all variables are
zero-initialised,
> rather than null-initialised. I think this will cause more problems than
it
> is intended to solve.

I understand your point, but I don't agree. There is really no missing a NaN value in one's output. But it's EASY to miss a spurious 0 or the effect of a spurious 0 on the output.

> Since everyone will always "know" that
> zero-initialisation is happening, the issue of whether one might forget to
> initialise it is moot: therefore there's no need for NaN.

I don't agree that forgetting to initialize something is the same thing as relying on it being initialized to 0. All I'm trying to accomplish here is helping people remember to think about what they need a floating point value's initial value to be.

> And wouldn't it just be better for the compiler to tell you at
compile-time
> that you've not initialised something,

It would be, except that it is not possible for the compiler to unambiguously determine that a variable is not initialized. This leads to putting in 'dummy' initializations to shut up the compiler, and the maintenance programmer is left to wondering why x is being set to a value that is never used.

> rather than you having potentially
> huge amounts of effort in tracing/debugging back to find that a variable
> started life as NaN instead of 0.0 ?

I'd be shocked if it was a huge effort. In fact, by the nature of how NaN's work, it should be much easier to trace back than a spurious 0. Also, 0's can affect your output in subtle ways and therefore go unnoticed. There is no unnoticing of a NaN output. If your intention is to write robust floating point code, NaN is the one to pick for unintended initializations.


February 04, 2004
At this point I give up... I've tried and tried, Walter seems to be unswayable on this one.

But he never did respond to the suggestion to use some other value to initialize integers.  Maybe at least that will happen.

Sean

Walter wrote:
| "Matthew" <matthew.hat@stlsoft.dot.org> wrote in message
| news:bvo60s$2nur$1@digitaldaemon.com...
|||| NaN seems arbitrarily inconsistent.
|||
||| That's only because there is no NaN value for integers.
||
|| Sure, but if consistency is what you're after, why choose 0 for
|| integers? Why not -1?
|
| Consistency is not possible because there is no NaN value for
| integers. So we just do the best we can.
|
||
|| Using 0 for integers merely leads us to the current mindset whereby
|| the expectation is the all variables are initialised to their "zero
|| value", rather than their "null value".
||
||| null is the NaN
||| value for pointers and references, and that is used, too.
||
|| Here's the way it looks to me:
||
|| 1. Pointers/references
||     do not have a "zero value"
||     "null value" is null
||
|| 2. Integers
||     "zero value" is 0
||     "null value" is 0
||
|| 3. Floating point
||     "zero value" is 0 (or 0.0, if you like)
||     "null value" is NaN
||
|| Since pointers/references do not have a "zero value", but their
|| "null value" is what one would choose to be if "zero value" had
|| meaning to pointers/references, I think there's a strong argument
|| that floating point's should be default initialised to their "zero
|| value" rather than their "null value" simply because that is what
|| everyone will expect.
||
||| Even better would
||| be if the CPU offered some way to tag a location as 'empty', but so
||| far, this does not exist outside of the 8087 registers.
||
||
|| I completely agree, and if integers had a well-known "null value"
|| then this argument would be moot.
||
|| Indeed, maybe we should decide that top-bit-set is the null value,
|| e.g. -128, -32768, etc ? I know this sounds silly, but it is
|| consistent with NaN. The reason it sounds silly is that we all know
|| that 0 is the "null value" of integers. Alas, this knowing is what
|| causes us all to believe that
|| 0.0 is the "null value" of floating points, which I grant you it's
|| not.
||
|||
|||| I agree that one will much more often want to rely on it being 0
|||| than NaN.
|||
||| The point is to provide a useless value so 'uninitialized' variable
||| problems will be exposed, and a consistent value to aid in tracking
||| the problem down.
|||
|||| Is the rationale for NaN documented anywhere? I'd like to read it.
|||
||| The idea is if you want to use it, you should set it to a value
||| first. The NaN is to catch paths where you used it but failed to
||| initialize it.
||
|| I understand that this is the intention, but since integers do not
|| have a "null value", and integer programming is far more common that
|| floating point, people will come to believe that all variables are
|| zero-initialised, rather than null-initialised. I think this will
|| cause more problems than it is intended to solve.
|
| I understand your point, but I don't agree. There is really no
| missing a NaN value in one's output. But it's EASY to miss a spurious
| 0 or the effect of a spurious 0 on the output.
|
|| Since everyone will always "know" that
|| zero-initialisation is happening, the issue of whether one might
|| forget to initialise it is moot: therefore there's no need for NaN.
|
| I don't agree that forgetting to initialize something is the same
| thing as relying on it being initialized to 0. All I'm trying to
| accomplish here is helping people remember to think about what they
| need a floating point value's initial value to be.
|
|| And wouldn't it just be better for the compiler to tell you at
|| compile-time that you've not initialised something,
|
| It would be, except that it is not possible for the compiler to
| unambiguously determine that a variable is not initialized. This
| leads to putting in 'dummy' initializations to shut up the compiler,
| and the maintenance programmer is left to wondering why x is being
| set to a value that is never used.
|
|| rather than you having potentially
|| huge amounts of effort in tracing/debugging back to find that a
|| variable started life as NaN instead of 0.0 ?
|
| I'd be shocked if it was a huge effort. In fact, by the nature of how
| NaN's work, it should be much easier to trace back than a spurious 0.
| Also, 0's can affect your output in subtle ways and therefore go
| unnoticed. There is no unnoticing of a NaN output. If your intention
| is to write robust floating point code, NaN is the one to pick for
| unintended initializations.


February 05, 2004
On Tue, 03 Feb 2004 13:19:43 -0800, Walter wrote:

[...]
> Also, 0's can affect your output in subtle ways and therefore go unnoticed.
[...]

Then please explain, why
| real value;
| printf("%d\n", cast(int) value);

leads to the output
| -2147483648

So long.
February 06, 2004
Manfred Nowak wrote:
> Then please explain, why
> | real value;
> | printf("%d\n", cast(int) value);
> 
> leads to the output
> | -2147483648

Should the cast maybe throw an exception here? Only in debug mode or always?

-eye

February 07, 2004
In article <c00gvg$1bt2$1@digitaldaemon.com>, Ilya Minkov says...
>
>Manfred Nowak wrote:
>> Then please explain, why
>> | real value;
>> | printf("%d\n", cast(int) value);
>> 
>> leads to the output
>> | -2147483648
>
>Should the cast maybe throw an exception here? Only in debug mode or always?

No, it should not. The point of cast is to have the calling function _consider_ the bit pattern as what the cast states.

While this may not be entirely in the spirit of D, the idiom
"cast" is an established concept (thanks(?) to C), and
therefore has to behave as such.

Cast in source code typically means that you tell the compiler that whatever it is you wrote, you know what you are doing.

Therefore, if you cast a float to integer, or an int array to char * void, that is what you get.

Because I'm not at my own computer right now, I cannot tell
whether the value -2147483648 represents a valid default
value for reals, or whether it is merely the bit pattern
that happened to be at the address at the time. But if it
turns out this is the default real value as viewed as an int,
then everything is ok. OTOH, if this is just a bit pattern,
(confirmable by running the program in different contexts
and comparing the output) then the compiler has forgotten
to initialize the float.



February 07, 2004
On Sat, 07 Feb 2004 08:16:34 +0000, Georg Wrede wrote:

[...]
> No, it should not. The point of cast is to have the calling function _consider_ the bit pattern as what the cast states.
[...]

Please check your statements before posting or do not post at all.

Setting a real variable to for example `3.141516' and then casting it to int outputs `3'. I have checked the bit pattern of the real variable there is no bit pattern for an int 3 in it.

So long.


February 07, 2004
"Sean L. Palmer" <palmer.sean@verizon.net> wrote in message news:bvrd8s$225h$1@digitaldaemon.com...
> But he never did respond to the suggestion to use some other value to initialize integers.  Maybe at least that will happen.

I just don't see much is gained by that. Anyhow, you can specify a default initializer for typedef's:

typedef int myint = 1;    // default initialize all myint's to 1