www.digitalmars.com         C & C++   DMDScript  

D - default float initialiser

reply imr1984 <imr1984_member pathlink.com> writes:
ok so the default initialiser for an integer is 0, so why is it nan for floats?
Surely 0.0f would be more logical & useful.
Feb 02 2004
next sibling parent der_held <der_held_member pathlink.com> writes:
ok so the default initialiser for an integer is 0, so why is it nan for floats?
Surely 0.0f would be more logical & useful.

initialized. nan is just perfect for that use.
Feb 02 2004
prev sibling next sibling parent yaneurao <yaneurao_member pathlink.com> writes:
In article <bvl7nc$abm$1 digitaldaemon.com>, imr1984 says...
ok so the default initialiser for an integer is 0, so why is it nan for floats?
Surely 0.0f would be more logical & useful.

I agree with you. sometimes I am annoyed with it. for example , in the following two case , the results are different. struct foo { union { float a; // initialized to nan int b; // initialized to 2143289344 }} struct foo { union { int b; // initialized to 0 float a; // initialized to 0.0 }} incidentally , it is better to be capable of initalizing by expression. eg. class X { Y y = new Y; int a[3] = [ 1,2,3 ]; } yaneurao.
Feb 02 2004
prev sibling parent reply Olaf Rogalsky <olaf.rogalsky theorie1.physik.uni-erlangen.de> writes:
imr1984 wrote:
 ok so the default initialiser for an integer is 0, 

me where to find it. Are automatic variables (of simple type) beeing initialized on entry of a function?
 so why is it nan for floats?
 Surely 0.0f would be more logical & useful.

variables explicitly, when needed. If I forget to initialize, a NaN is more usesfull than 0.0. 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 +-------------------------------------------------------------------+
Feb 02 2004
next sibling parent reply Sebastian Beschke <s.beschke gmx.de> writes:
Olaf Rogalsky wrote:
 This seem to be a matter of personal taste. I prefer to initialize
 variables explicitly, when needed. If I forget to initialize, a NaN
 is more usesfull than 0.0.

Exactly. I prefer to go the C-way: Never use a variable without initializing it. For that matter, I don't think even ints need to be initialized. Explicitly initializing variables makes things somewhat clearer to read. Sebastian
Feb 02 2004
parent "davepermen" <davepermen hotmail.com> writes:
the reason they have a default value is only the ability to repeat
situations. useful for debuging, as situations are 100% determinable, only
depending on external functions (user input, timers, etc).

helps a bunch.

they don't need a rather meaningful value for this. NaN is perfect.

"Sebastian Beschke" <s.beschke gmx.de> schrieb im Newsbeitrag
news:bvll7k$vh2$1 digitaldaemon.com...
 Olaf Rogalsky wrote:
 This seem to be a matter of personal taste. I prefer to initialize
 variables explicitly, when needed. If I forget to initialize, a NaN
 is more usesfull than 0.0.

Exactly. I prefer to go the C-way: Never use a variable without initializing it. For that matter, I don't think even ints need to be initialized. Explicitly initializing variables makes things somewhat clearer to read. Sebastian

Feb 02 2004
prev sibling next sibling parent reply "Sean L. Palmer" <palmer.sean verizon.net> writes:
This has been talked to death already.  Some of us would rather have
uninitialized variables be an error, but Walter doesn't like that because
you'd have to initialize some variables twice to get the compiler to shut
up.  I'm in the camp that defaults should be useful rather than pitfalls you
have to avoid anyway.  I find NaN default initialization just one teensy bit
nicer than garbage, but it would be far superior to initialize to something
that is potentially useful.

I find that I *want* to initialize to 0.0 far far far more often than I want
to initialize to NaN.  The way it is now, uninitialized variables are just
guaranteed to bite you in the ass at runtime, instead of randomly, which is
good, but I'd rather it bite you at compile time.

Sean

Olaf Rogalsky wrote:
| imr1984 wrote:
|| ok so the default initialiser for an integer is 0,
| Can't find this is in the manual, can anybody advise
| me where to find it. Are automatic variables (of simple type)
| beeing initialized on entry of a function?
|
|| so why is it nan for floats?
|| Surely 0.0f would be more logical & useful.
| This seem to be a matter of personal taste. I prefer to initialize
| variables explicitly, when needed. If I forget to initialize, a NaN
| is more usesfull than 0.0.
|
| Olaf
Feb 02 2004
parent reply "Matthew" <matthew.hat stlsoft.dot.org> writes:
NaN seems arbitrarily inconsistent.

I agree that one will much more often want to rely on it being 0 than NaN.

Is the rationale for NaN documented anywhere? I'd like to read it.

"Sean L. Palmer" <palmer.sean verizon.net> wrote in message
news:bvmk0p$2jip$1 digitaldaemon.com...
 This has been talked to death already.  Some of us would rather have
 uninitialized variables be an error, but Walter doesn't like that because
 you'd have to initialize some variables twice to get the compiler to shut
 up.  I'm in the camp that defaults should be useful rather than pitfalls

 have to avoid anyway.  I find NaN default initialization just one teensy

 nicer than garbage, but it would be far superior to initialize to

 that is potentially useful.

 I find that I *want* to initialize to 0.0 far far far more often than I

 to initialize to NaN.  The way it is now, uninitialized variables are just
 guaranteed to bite you in the ass at runtime, instead of randomly, which

 good, but I'd rather it bite you at compile time.

 Sean

 Olaf Rogalsky wrote:
 | imr1984 wrote:
 || ok so the default initialiser for an integer is 0,
 | Can't find this is in the manual, can anybody advise
 | me where to find it. Are automatic variables (of simple type)
 | beeing initialized on entry of a function?
 |
 || so why is it nan for floats?
 || Surely 0.0f would be more logical & useful.
 | This seem to be a matter of personal taste. I prefer to initialize
 | variables explicitly, when needed. If I forget to initialize, a NaN
 | is more usesfull than 0.0.
 |
 | Olaf

Feb 02 2004
parent reply "Walter" <walter digitalmars.com> writes:
"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.
 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.
Feb 02 2004
next sibling parent "Sean L. Palmer" <palmer.sean verizon.net> writes:
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
Feb 03 2004
prev sibling parent reply "Matthew" <matthew.hat stlsoft.dot.org> writes:
 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


 The point is to provide a useless value so 'uninitialized' variable

 will be exposed, and a consistent value to aid in tracking the problem

 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 ?
Feb 03 2004
parent reply "Walter" <walter digitalmars.com> writes:
"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

 is what one would choose to be if "zero value" had meaning to
 pointers/references, I think there's a strong argument that floating

 should be default initialised to their "zero value" rather than their

 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

 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

 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

 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


 The point is to provide a useless value so 'uninitialized' variable

 will be exposed, and a consistent value to aid in tracking the problem

 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.


 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

 rather than null-initialised. I think this will cause more problems than

 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

 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.
Feb 03 2004
next sibling parent reply "Sean L. Palmer" <palmer.sean verizon.net> writes:
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.
Feb 04 2004
parent "Walter" <walter digitalmars.com> writes:
"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
Feb 07 2004
prev sibling next sibling parent reply Manfred Nowak <svv1999 hotmail.com> writes:
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.
Feb 05 2004
parent reply Ilya Minkov <minkov cs.tum.edu> writes:
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
Feb 06 2004
next sibling parent reply Georg Wrede <Georg_member pathlink.com> writes:
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.
Feb 07 2004
parent reply Manfred Nowak <svv1999 hotmail.com> writes:
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.
Feb 07 2004
parent reply Georg Wrede <Georg_member pathlink.com> writes:
In article <c02rb2$2ps5$1 digitaldaemon.com>, Manfred Nowak says...
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.

Thanks for the prompt correction! It's good somebody is awake at the keyboard, before too many newbies learn the wrong thing. I musta had a serious blackout! :-/
Feb 07 2004
parent "Jan-Eric Duden" <jeduden whisset.com> writes:
I think fortran behave in the way that you described. ;)
-- 
Jan-Eric Duden
"Georg Wrede" <Georg_member pathlink.com> wrote in message
news:c03nkk$17eq$1 digitaldaemon.com...
 In article <c02rb2$2ps5$1 digitaldaemon.com>, Manfred Nowak says...
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


is no bit pattern for an int 3 in it.

Thanks for the prompt correction! It's good somebody is awake at the keyboard, before too many newbies learn the wrong thing. I musta had a serious blackout! :-/

Feb 16 2004
prev sibling parent "Walter" <walter digitalmars.com> writes:
"Ilya Minkov" <minkov cs.tum.edu> wrote in message
news:c00gvg$1bt2$1 digitaldaemon.com...
 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

Casting a nan to an int sets the "invalid" flag in the FPU. These flags are sticky; you can test for them using the C function fegetexcept().
Feb 07 2004
prev sibling parent reply "Jan-Eric Duden" <jeduden whisset.com> writes:
 "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


 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

 is what one would choose to be if "zero value" had meaning to
 pointers/references, I think there's a strong argument that floating

 should be default initialised to their "zero value" rather than their

 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



 this does not exist outside of the 8087 registers.

I completely agree, and if integers had a well-known "null value" then

 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

 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

 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




 NaN.
 The point is to provide a useless value so 'uninitialized' variable

 will be exposed, and a consistent value to aid in tracking the problem

 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.


 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


 "null value", and integer programming is far more common that floating
 point, people will come to believe that all variables are

 rather than null-initialised. I think this will cause more problems than

 is intended to solve.

I understand your point, but I don't agree. There is really no missing a

 value in one's output. But it's EASY to miss a spurious 0 or the effect of

 spurious 0 on the output.

You can apply this argument on integers as well which are initialized with 0.
 Since everyone will always "know" that
 zero-initialisation is happening, the issue of whether one might forget


 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.

If you want to remind people then issue an warning. That is explicit and will be seen by everyone. Relying on a weird output does not apply to all problems that a general purpose language is used for. Imagine a 3D Engine: You do not see the values of the floats - you just see triangles. So bugs like that are not easy to catch.
 And wouldn't it just be better for the compiler to tell you at

 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

 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

 point code, NaN is the one to pick for unintended initializations.

you are fighting against: dummy initialization. It might turn out that most people will just initialize all their floats with 0.0, just to have a good starting point. So it seems like both approaches NaN and compiler warnings can lead to dummy initialization, depending on what people develop. So why not initialize to 0? Generally speaking, floats and integers are almost the same. You can add them, you subtract them, divide and so on. They are just numbers. Consider templates: Make a templated class using numbers. Instanciate the template with integers and with floats. Both instances use numbers in general. But the integers are initialized with 0 and the floats with NaN! That is not really straight forward, especially if people don't know what NaNs are. They are wondering what the heck is that? The concept of NaNs is specific to certain applications of floats. I think usually NaNs don't occur. So why do you want to introduce NaN to applications that would never have to deal with them? BTW, what is the result of "1 divided by NaN" on Win95/98 in D? Personally, I think what people helps not to make mistakes are simple concepts. An easy concepts are: all variables are initialized with garbage. all variables are initialized with 0. The following concept is not easy: All variables are initalized with the "null-value". Null values of references are "null". Null values of integers are 0. Null values of floats are NaN. Furthmore, if you consider the background of most people that have programming expierence. They come from languages where floats are initialized with 0 by default or with garbage. So what do you think they will assume about the default value of floats when they figured out that integers are initialized with 0 and references with null? NaN? I don't think so. Is there any language that initializes floats with NaN? All the languages I know just don't initialize or do it with 0, that is another reason for newbies to assume a float default value of 0. 0 is such a nice number! How often do I write in constructors memset(this,0,sizeof(*this)); .... Cheers, Jan-Eric
Feb 16 2004
parent Ilya Minkov <minkov cs.tum.edu> writes:
Jan-Eric Duden wrote:
 If you want to remind people  then issue an warning.
 That is explicit and will be seen by everyone.
 Relying on a weird output does not apply to all problems that a general
 purpose language is used for.
 Imagine a 3D Engine: You do not see the values of the floats - you just see
 triangles. So bugs like that are not easy to catch.

That's what Design By Contract is intended for. Whenever you use a NaN in an expression, result is also NaN. Thus it is enough to insert a contract on the very final stage of the engine to ensure that the complete engine is bug-free. If there are any, this means the program is buggy and more earlier contracts have to be inserted to track it down. I think also any operation with NaN sets the error flag, which could automatcally be checked at all return points of a function and exception raised. This would easily show where the problem first comes to light. Of course, there must be a well-defined way to clear the error flag.
 I think initializing floats variables with NaN can lead to the same problem
 you are fighting against: dummy initialization.
 It might turn out that most people will just initialize all their floats
 with 0.0, just to have a good starting point.

 So it seems like both approaches NaN and compiler warnings can lead to dummy
 initialization, depending on what people
 develop. So why not initialize to 0?

One cannot be everyone's doctor. People are usually educated from C++ and Java use that floats (just as anything else) should be initialised with a sane value, just before use. 0.0 is not too often what you want with floats, and if you do you just know to remember it. However, in C++ values are initailised with bit noise. This means that if you by some occasion put initialisation at some point which gets skipped (whoops!) or forget to initialise in a certain code path (whoops!) then you get a bit pattern. You can track it itself with a debugger, however you cannot get automatically warned, since the number that it represents is actually fully legal - because the same pattern had to be for everything. And after a few operations you don't have a problem indication, just silly plain false results. And it's just not any different with 0. But with NaN you have NaN in a final result which is easy to ensure that it does not happen. And like, you don't have a global SillyArray, and initialise every pointer to point into it when you don't know any better value? You initialise it with null! So that the program would crash when using it, thus indicating a failure.
 Generally speaking, floats and integers are almost the same. You can add
 them, you subtract them, divide and so on.
 They are just numbers.

Floats by definition have significant problems that every programmer should be aware of. Besides, floats are usually numeric values, and integers are usually simply counters. So i don't buy that argument.
 Consider templates: Make a templated class using numbers. Instanciate the
 template with integers and with floats.
 Both instances use numbers in general. But the integers are initialized with
 0 and the floats with NaN!

Templates are written by library writers, professionals. If a template is not numeric, then the initailization doesn't actually matter since it is transparent. If a template is numeric and requieres a specific start value for calculations, it is up to template designer to ensure that it gets initailised correctly. If it is up to user to initialise the values - again, NaN allows to dagnosticise a problem at some point.
 That is not really straight forward, especially if people don't know what
 NaNs are.
 They are wondering what the heck is that?
 The concept of NaNs is specific to certain applications of floats.
 I think usually NaNs don't occur.
 So why do you want to introduce NaN to applications that would never have to
 deal with them?

This is good that NaNs usually don't occur - relying on NaNs in an application would make them unusable for debugging. And theother way around, numeric code relying on NaNs to *work* would be an unworkable nonsense. There was a big argument on what to do when an illegal operation is beling made. Obviously, you can recall what happens if you integer divide by zero? The dreaded CPU Exception 200, which terminates the application. This was clearly unacceptable for numeric work, and so a special value was reserved to indicate errors for late checks or due to illegal input. So why not use it? Besides, what's the language manual for? Of course it should contain explaination what NaNs are and why. You don't just go off and program in a language you don't know without having read the manual, do you? Don't consider the current spec a manual, it has yet a long way to go and is intended for people who know what this&that is or can look up elsewhere on their own.
 Personally, I think what people helps not to make mistakes are simple
 concepts.
 An easy concepts are:
 all variables are initialized with garbage.

Very, very evil.
 all variables are initialized with 0.

This may be not bad, but then again it's not nearly as helpful as NaN.
 The following concept is not easy:
 All variables are initalized with the "null-value". Null values of
 references are "null". Null values of integers are 0. Null values of floats
 are NaN.

It's the most practical one. Don't consider programmers stupid! And if it does get in the way, then in a fairly easy to diagnosticize way.
 Furthmore, if you consider the background of most people that have
 programming expierence.
 They come from languages where floats are initialized with 0 by default or
 with garbage. So what do you think they will assume about the default value
 of floats when they figured out that integers are initialized with 0 and
 references with null?  NaN? I don't think so.

Then let them program as if it were garbage even, it won't make it any worse than they would now. Again: what practical improvement would you see from zero init or from real garbage init?
 Is there any language that initializes floats with NaN?
 All the languages I know just don't initialize or do it with 0, that is
 another reason for newbies to assume a float default value of 0.

Don't be so narrow-minded. I think someone can come up with one. Besides, i ask you, is garbage any better than NaN? C & C++ DoItWithGarbage(tm) :> Besides, if we do everything like the others, where would the progress be? D has been blamed for being not innovative enogh, but i argue that this subtle point with NaN init is one of the key innovations in D.
 0 is such a nice number! How often do I write in constructors
 memset(this,0,sizeof(*this)); ....

Uh-oh! That's what programmers had to spend ther time with before D came. ;> Besides, memset to 0 doesn't guarantee much useful, besides that integers are initialised to 0. Floating-point and pointers may have (in principle) 0 or null represented in a different bit-pattern! Though this may have worked on our machines for years... -eye
Feb 17 2004
prev sibling parent reply J C Calvarese <jcc7 cox.net> writes:
Olaf Rogalsky wrote:
 imr1984 wrote:
 
ok so the default initialiser for an integer is 0, 

Can't find this is in the manual, can anybody advise me where to find it.

It says it twice if you look hard enough... .init initializer (0) int.init // is 0 -- Justin http://jcc_7.tripod.com/d/
Feb 02 2004
parent Olaf Rogalsky <olaf.rogalsky theorie1.physik.uni-erlangen.de> writes:
J C Calvarese wrote:
 http://www.digitalmars.com/d/property.html
 
 It says it twice if you look hard enough...

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 +-------------------------------------------------------------------+
Feb 03 2004