Jump to page: 1 2
Thread overview
Floating point types default to NaN?
Nov 24, 2017
Adam D. Ruppe
Nov 24, 2017
Jonathan M Davis
Nov 25, 2017
Dave Jones
Nov 25, 2017
Adam D. Ruppe
Nov 27, 2017
Adam D. Ruppe
Nov 27, 2017
Dukc
Nov 27, 2017
Adam D. Ruppe
Nov 30, 2017
codephantom
November 24, 2017
I would have expected 0 to be the default value. What's the logic behind having them being NaN by default?

https://dlang.org/spec/type.html
November 24, 2017
On Friday, 24 November 2017 at 14:30:44 UTC, A Guy With a Question wrote:
> I would have expected 0 to be the default value. What's the logic behind having them being NaN by default?


It gives you a runtime error (sort of) if you use an uninitialized variable.

You ARE supposed to explicitly initialize variables to your own values in D. The automatic init is to make errors stand out more consistently if you don't do this as opposed to being random.

So pointers are initialized to null - an invalid value that stands out if you try to use it. chars get \xFF - again, invalid that will throw if you try to utf decode it. Floats get NaN which is as close to invalid as they get.

ints happen to get 0 not to be convenient, but because there is no clearly-invalid int value so something had to be chosen, and 0 was just easy to implement....
November 24, 2017
On Friday, 24 November 2017 at 14:43:24 UTC, Adam D. Ruppe wrote:
> On Friday, 24 November 2017 at 14:30:44 UTC, A Guy With a Question wrote:
>> I would have expected 0 to be the default value. What's the logic behind having them being NaN by default?
>
>
> It gives you a runtime error (sort of) if you use an uninitialized variable.
>
> You ARE supposed to explicitly initialize variables to your own values in D. The automatic init is to make errors stand out more consistently if you don't do this as opposed to being random.
>
> So pointers are initialized to null - an invalid value that stands out if you try to use it. chars get \xFF - again, invalid that will throw if you try to utf decode it. Floats get NaN which is as close to invalid as they get.
>
> ints happen to get 0 not to be convenient, but because there is no clearly-invalid int value so something had to be chosen, and 0 was just easy to implement....

If thats the case why not just throw a compiler error? D has a way explicitly not set it right? Through void...So if the intent is to find erroneous code right away, just throw a compiler error no?

November 24, 2017
On Friday, November 24, 2017 20:43:14 A Guy With a Question via Digitalmars- d-learn wrote:
> On Friday, 24 November 2017 at 14:43:24 UTC, Adam D. Ruppe wrote:
> > On Friday, 24 November 2017 at 14:30:44 UTC, A Guy With a
> >
> > Question wrote:
> >> I would have expected 0 to be the default value. What's the logic behind having them being NaN by default?
> >
> > It gives you a runtime error (sort of) if you use an
> > uninitialized variable.
> >
> > You ARE supposed to explicitly initialize variables to your own values in D. The automatic init is to make errors stand out more consistently if you don't do this as opposed to being random.
> >
> > So pointers are initialized to null - an invalid value that stands out if you try to use it. chars get \xFF - again, invalid that will throw if you try to utf decode it. Floats get NaN which is as close to invalid as they get.
> >
> > ints happen to get 0 not to be convenient, but because there is no clearly-invalid int value so something had to be chosen, and 0 was just easy to implement....
>
> If thats the case why not just throw a compiler error? D has a way explicitly not set it right? Through void...So if the intent is to find erroneous code right away, just throw a compiler error no?

That requires data flow analysis, which the compiler doesn't do a lot of, because it can be complicated. It also tends to result in the compiler giving warnings or errors in cases where it's not actually true that the variable is used before it's given a value, because it can't do it perfectly. There was a recent discussion on this in the main newsgroup with regards to guaranteeing with a pointer or reference was initialized to something other than null.

Also, when you start having stuff like arrays, having a default initializer is a big boon, since then all of the elements have a default value. It's going to work even worse to try and have the compiler detect when you've properly initialized every element in an array than have it detect when you've properly initialized just a variable. And stuff like the out attribute relies on there being a default initializer. Just all around, having default initializers for types in general makes things cleaner and less error-prone.

And NaN math is something that's built into CPU. Operations other than default initialization can result in a floating point value being NaN. So, if you're looking to have NaN not be a thing for floating point values, then you're out of luck. And Walter is a big fan of NaN being a thing, since when you hit it, you know that you've found a bug, and tracking it down tends to be fairly straightforward, which is not the case with many other types of bugs.

- Jonathan M Davis

November 25, 2017
On Friday, 24 November 2017 at 22:38:49 UTC, Jonathan M Davis wrote:
> On Friday, November 24, 2017 20:43:14 A Guy With a Question via Digitalmars- d-learn wrote:
>> On Friday, 24 November 2017 at 14:43:24 UTC, Adam D. Ruppe
> That requires data flow analysis, which the compiler doesn't do a lot of, because it can be complicated. It also tends to result in the compiler giving warnings or errors in cases where it's not actually true that the variable is used before it's given a value, because it can't do it perfectly. There was a recent discussion on this in the main newsgroup with regards to guaranteeing with a pointer or reference was initialized to something other than null.

I think he means just spew an error if a float is declared but not explicitly initialised... Whats the problem with...

float foo; // compiler error "floats must be explicitly initialised"
float foo = float.nan; // old behaviour.

I mean at the end of the day, that would turn a run time error into a compile time error which is a good thing isnt it?


November 25, 2017
On Friday, 24 November 2017 at 22:38:49 UTC, Jonathan M Davis wrote:
> That requires data flow analysis, which the compiler doesn't do a lot of, because it can be complicated.

If dataflow is sufficient then it isn't all that complicated, you can implement generic dataflow using Monotone Frameworks:

http://symbolaris.com/course/Compilers11/27-monframework.pdf

But on the other hand, data flow might not be sufficient for what you want to do.

> And NaN math is something that's built into CPU. Operations other than default initialization can result in a floating point value being NaN.

If you have turned on exceptions for signalling-NaNs then it makes sense. It doesn't make all that much sense for quiet NaNs.

November 25, 2017
On Saturday, 25 November 2017 at 09:39:15 UTC, Dave Jones wrote:
> On Friday, 24 November 2017 at 22:38:49 UTC, Jonathan M Davis wrote:
>> On Friday, November 24, 2017 20:43:14 A Guy With a Question via Digitalmars- d-learn wrote:
>>> On Friday, 24 November 2017 at 14:43:24 UTC, Adam D. Ruppe
>> That requires data flow analysis, which the compiler doesn't do a lot of, because it can be complicated. It also tends to result in the compiler giving warnings or errors in cases where it's not actually true that the variable is used before it's given a value, because it can't do it perfectly. There was a recent discussion on this in the main newsgroup with regards to guaranteeing with a pointer or reference was initialized to something other than null.
>
> I think he means just spew an error if a float is declared but not explicitly initialised... Whats the problem with...
>
> float foo; // compiler error "floats must be explicitly initialised"
> float foo = float.nan; // old behaviour.
>
> I mean at the end of the day, that would turn a run time error into a compile time error which is a good thing isnt it?

That is exactly what I meant. I think most languages just choose to default it to something convenient, which is 0. C++ chooses not to default it for speed reasons. If D chooses it's defaults to make errors stick out, why not just error at declaration if they don't explicitly set it to something. Including void, which would give you C++ undefined behavior from what I've read so far.


November 25, 2017
Nonetheless, my original question was answered. Thanks for the insights!
November 25, 2017
On Saturday, 25 November 2017 at 16:16:52 UTC, A Guy With a Question wrote:
> If D chooses it's defaults to make errors stick out, why not just error at declaration if they don't explicitly set it to something.

It technically did:

https://dlang.org/spec/function.html#local-variables

"It is an error to use a local variable without first assigning it a value. The implementation may not always be able to detect these cases. Other language compilers sometimes issue a warning for this, but since it is always a bug, it should be an error. "


But that paragraph was never implemented (it is a bit easier said than done to actually detect given if conditions and stuff too, especially in the early days of D when the compiler didn't even make any effort to track such things, though it does now...). The compiler author took the easy way out of initializing them to invalid values instead.

While it is more realistic to implement technically now than it was years ago when the current behavior got in, I think we're at the point now that so many people use it as a convenience thing on ints and nulls that there'd be hell to pay if the compiler actually started calling it an error :(

November 25, 2017
On Saturday, 25 November 2017 at 22:13:43 UTC, Adam D. Ruppe wrote:
> On Saturday, 25 November 2017 at 16:16:52 UTC, A Guy With a Question wrote:
>> If D chooses it's defaults to make errors stick out, why not just error at declaration if they don't explicitly set it to something.
>
> It technically did:
>
> https://dlang.org/spec/function.html#local-variables
>
> "It is an error to use a local variable without first assigning it a value. The implementation may not always be able to detect these cases. Other language compilers sometimes issue a warning for this, but since it is always a bug, it should be an error. "
>
>
> But that paragraph was never implemented (it is a bit easier said than done to actually detect given if conditions and stuff too, especially in the early days of D when the compiler didn't even make any effort to track such things, though it does now...). The compiler author took the easy way out of initializing them to invalid values instead.
>
> While it is more realistic to implement technically now than it was years ago when the current behavior got in, I think we're at the point now that so many people use it as a convenience thing on ints and nulls that there'd be hell to pay if the compiler actually started calling it an error :(

Fair enough!
« First   ‹ Prev
1 2