digitalmars.D - float init 0 request
- ABrightLight (40/40) Aug 13 Hello. I understand this subject's been discussed a number of
- Walter Bright (13/13) Aug 13 Floats are default initialized to NaN so people will be coerced to expli...
- Alexandru Ermicioi (4/8) Aug 14 Why not make it an error, a float that is not explicitly
- Jonathan M Davis (22/31) Aug 14 The language relies on the ability to default-initialize objects. For
- Alexandru Ermicioi (6/23) Aug 14 Right, that would cause mayhem in templated code, an extra static
- Indraj Gandham (9/24) Aug 14 This is a valid point, but it merely implies that there should be
- Walter Bright (9/11) Aug 14 All it takes is one unintentional default initialization of 0.0 which le...
- Mindy Batek (0xEAB) (9/13) Aug 14 For graphic applications, it can lead to a minor detail not
- claptrap (6/10) Aug 15 You haven't solved this problem, the guy who sees an
- Richard (Rikki) Andrew Cattermole (8/19) Aug 14 This only works without false positives in limited cases.
- Walter Bright (6/9) Aug 14 This requires Data Flow Analysis, which slows the compiler down. It's no...
- claptrap (4/21) Aug 15 Make it an error where it can be detected, for fields and locals.
- Walter Bright (12/14) Aug 14 Because then you wind up with:
- Richard (Rikki) Andrew Cattermole (7/26) Aug 14 Alternatively make the parameter out:
- Walter Bright (2/11) Aug 14 `out` will default initialize `v` to NaN upon entry to the function!
- claptrap (4/20) Aug 15 And yet that is exactly what you have the compiler doing,
- Riven (15/18) Aug 15 So:
- Indraj Gandham (9/14) Aug 14 It's not similar at all. There is no sensible init value for a
- monkyyy (6/7) Aug 14 There is, especially for a gc language; theres at least 3 great
- Walter Bright (17/31) Aug 14 I'm afraid we disagree. The null pointer initialization ensures that you...
- Mindy Batek (0xEAB) (3/6) Aug 14 This is, unironically, a surprisingly accurate description of the
- claptrap (17/45) Aug 15 It's not a guarantee though is it. NaN is a valid result of some
- Walter Bright (3/4) Aug 19 You are correct that it is not foolproof, but it is far better than 0, b...
- Indraj Gandham (29/47) Aug 17 The difference is that the null ptr will always cause your
- Walter Bright (20/24) Aug 19 And that is exactly the point of NaN - to be incorrect, and to stand out...
- Steven Schveighoffer (9/25) Aug 20 This contrived almost impossible to occur scenario where zero
- monkyyy (3/11) Aug 20 Airplane surgery is very complicated.
- Mindy Batek (0xEAB) (5/11) Aug 17 But NaN as default init value is not like a defective sensor
- ABrightLight (12/28) Aug 14 Hi Walter, I really appreciate the response, however I think that
- Richard (Rikki) Andrew Cattermole (14/42) Aug 14 Unfortunately this is a good example of Walter leaving out the analysis,...
- Walter Bright (8/18) Aug 14 Signalling NaNs simply did not work unless you wrote your code in assemb...
- Richard (Rikki) Andrew Cattermole (4/10) Aug 14 The only thing you and I disagree on for NaN's is how much static
- claptrap (6/12) Aug 15 The old Delphi compiler did, backing the 2000s, no idea if it
- Walter Bright (3/8) Aug 14 I responded to that multiple times :-/
- monkyyy (3/14) Aug 14 recently trump said "house prices should go up"; that may in fact
- An (5/16) Aug 14 D advocates for unittest -> what happen to it?
- Quirin Schroll (12/14) Aug 17 Maybe the next D Edition could require initialization of types
- Richard (Rikki) Andrew Cattermole (2/17) Aug 17 Just keep in mind that this cannot cover all cases, like heap allocation...
- libxmoc (8/25) Aug 17 I don't think it's wise to change, it'll cause too much friction
- Adam D. Ruppe (6/8) Aug 17 This is actually what put me over the edge on making the change
- Walter Bright (8/11) Aug 17 C and C++ still do not default initialize stack variables to anything ot...
- Richard (Rikki) Andrew Cattermole (2/5) Aug 17 -preview=fastdfa says otherwise. So many of the C tests fail due to this...
- Indraj Gandham (4/17) Aug 17 Very little code would be impacted, as shown by OpenD's
- jmh530 (4/8) Aug 17 "Small QoL improvement...could be implemented in upstream today"
- Indraj Gandham (5/8) Aug 17 You are referring to this change as if it is a hypothetical. In
- Sergey (5/9) Aug 17 Don't forget that OpenD has limited usage as well.
- monkyyy (3/13) Aug 17 :spray_bottle:
- Nick Treleaven (10/13) Aug 17 My understanding is that an older edition will eventually stop
- Steven Schveighoffer (4/8) Aug 17 I don't think we are supposed to stop supporting any specific
- Richard (Rikki) Andrew Cattermole (2/12) Aug 17 Eventually we will, but it'll be like 20+ years.
- Nick Treleaven (4/12) Aug 19 Even if that were true, it should not be unreasonably hard to
- Dukc (14/26) Aug 17 When done well (like in Haskell or Rust) I also think the best
- Walter Bright (4/9) Aug 19 My reply to this seems to have disappeared.
- Serg Gini (17/28) Aug 19 C++:
- user1234 (6/37) Aug 19 I think that your answer is a bit out-of-topic. We started on
- user1234 (4/13) Aug 19 sorry about the little inacuraccy, I was refering to Scott Meyers
- Steven Schveighoffer (10/18) Aug 19 D:
- monkyyy (3/12) Aug 19 1 :)
- Mike Shah (10/26) Aug 17 It's helped me more than a handful of times when building a
- Richard (Rikki) Andrew Cattermole (9/44) Aug 14 I mentioned this else where, the reason it doesn't cause a hardware
- Walter Bright (2/2) Aug 14 Another problem with NaN signalling an exception is no longer having a v...
- Kapendev (22/25) Aug 14 I'm in the `float.init = 0` team only because I know most people
- Walter Bright (8/10) Aug 14 You can set a default value for struct fields like this:
- Steven Schveighoffer (10/13) Aug 14 In all the years I have used D, whenever I have forgotten to
- Walter Bright (19/19) Aug 14 Ada was developed to be a safe language before NaNs existed. Being curio...
- monkyyy (8/10) Aug 15 We dont care about outsider theory, our **repeated** *personal*
- Kapendev (2/14) Aug 15 I agree with this guy 👆🙏
- Mindy Batek (0xEAB) (2/3) Aug 15 Let them who has run into this only once cast the first stone.
- Walter Bright (17/28) Aug 15 Sorry you had a bad initial experience with this.
- monkyyy (11/18) Aug 15 false 0's are not unnoticeable they render at the origin or as
- Walter Bright (10/12) Aug 19 Use this for data structures:
- monkyyy (5/11) Aug 20 I dont use a linter, your asking me to remember to do that every
- Kapendev (3/15) Aug 20 Happy ending.
- Kapendev (3/4) Aug 20 As a junior PHP web dev, I support NaN and don't support video
- Walter Bright (17/22) Aug 14 Yes, initializing to 0.0 is very common. And that works fine until the c...
- pete (36/40) Aug 15 I guess it depends upon the use case. In my experience with
- Walter Bright (6/10) Aug 15 will default initialize .depth to 0.0. May I suggest doing a grep across...
- pete (16/24) Aug 16 I usually do this now but I occasionally forget and it would not
- Walter Bright (5/8) Aug 18 If 0.0 is the wrong initialization, then it is worse trying to detect th...
- monkyyy (7/9) Aug 18 The point of floats is to be pretend analog signals, handling
- Walter Bright (2/8) Aug 18 The purpose of NaN is to expose errors, not hide them.
- Serg Gini (7/11) Aug 17 I think we should stop comparing with 50 years old languages. The
- Juraj (13/24) Aug 17 The main issue is `float.init`.
- Walter Bright (3/15) Aug 15 If you leave it as a C file, and then import it using Import C, the defa...
- libxmoc (3/18) Aug 16 Would scoping 0 initialization to extern(C) struct (or under
- Walter Bright (4/6) Aug 16 It would break the language into two incompatible dialects.
- Richard (Rikki) Andrew Cattermole (6/14) Aug 16 Except that isn't quite true ;)
- Walter Bright (3/9) Aug 16 It's a good point, but it still affects calling conventions because it a...
- pete (15/15) Aug 17 There is something I don't understand here. If an uninitialised
- Guillaume Piolat (4/8) Aug 17 Change NaN with null and you'll see how that argument doesn't
- pete (8/18) Aug 17 I do agree partially with this argument but at least a null will
- Richard (Rikki) Andrew Cattermole (14/23) Aug 17 But it does stand.
- user1234 (14/19) Aug 17 My understanding is that this would require complex static
- Walter Bright (21/25) Aug 17 Because of code like this:
- pete (14/41) Aug 18 I agree this looks a bit inelegant in this example. For more
- Walter Bright (12/12) Aug 18 Thank you for your thoughts on this. It would be even better if there wa...
- H. S. Teoh (10/16) Aug 18 D might as well use integer types for char, because char, wchar, and
- Nick Treleaven (27/32) Aug 19 No:
- Nick Treleaven (11/17) Aug 19 Sorry, that does error actually - string ~ byte does work:
- Jonathan M Davis (12/25) Aug 19 I think that we're still better off with having character types, because...
- Walter Bright (18/18) Aug 19 Casting is a hammer that overrides the type system. Hence one can plausi...
- Steven Schveighoffer (20/22) Aug 19 ```d
- Walter Bright (15/34) Aug 19 It does what it says on the box - gives 5 code units.
- H. S. Teoh (11/17) Aug 19 [...]
- Steven Schveighoffer (11/28) Aug 20 It does not. Given the first statement's behavior, you would
- H. S. Teoh (15/23) Aug 19 And that is where things go wrong. Upper/lowercasing via arithmetic
- Walter Bright (13/26) Aug 19 Since you don't like the casing example, consider string-to-decimal and
- H. S. Teoh (21/27) Aug 19 [...]
- Luna (17/33) Aug 20 Other countries with less simplistic type systems had their own
- Jonathan M Davis (53/71) Aug 19 D has definitely done a better job with type conversions than any other
- Richard (Rikki) Andrew Cattermole (10/23) Aug 18 I'm ok with this, however this is going to be a pretty invasive change
- Forum User (10/24) Aug 19 Regardless of how the value `f` is initialzed, this style
- Steven Schveighoffer (47/75) Aug 16 1. If this was the correct value, I would initialize it to 0.001.
- Walter Bright (5/5) Aug 16 Thank you for the excellent summary of your question. I believe I have r...
- Richard (Rikki) Andrew Cattermole (2/8) Aug 16 Sounds like a lightning talk to me.
- Guillaume Piolat (14/17) Aug 16 There is nothing to "fix" because NaN init is the right choice.
- Dukc (9/19) Aug 17 I don't think so. Using NaN will result in another NaN, so
- GB (18/59) Aug 20 The debate is treating a symptom-management mechanism as though
Hello. I understand this subject's been discussed a number of times before, but I'd like to throw in my reasoning for why it would benefit us more for floats to initialize to 0 than NaN. 1. float is generally used for numeric computation (things like NaN boxing are examples of uses outside of this) and as such have similarity to the integer types (they will even implicitly coerce mathematical operations to float). Since integers default to 0, floats should too. 1a. It may be argued that integers only default to 0 because there is no meaningful "null" value, but in my opinion this is not convincing because I think that most people would opt for them getting a reasonable default value right from the start instead of being forced to `= 0;` It is very common to see loop variables and other forms just say `int i;` or similar, and no one is confused by this. 2. It is argued that since, like pointers that have `null` and are default initialized to this, floats should also initialize to its version of `null`. However this is a false equivalence since the use of a null pointer is specified/standardized to crash the program due to a concern for memory safety (it's not even set to undefined behavior, a program halt must occur). The same memory safety concern is not present for most operations relying on floats, and the existence of NaN being left without a crash [or even an exception thrown] is to cater to performance. For cases where debugging by program halt is required, most of the time the approach done is for a compiler switch to allow throwing an exception instead of just halting the program, since a stack trace is presumed to be desired. 3. I know that rikki's DFA implementation will be able to detect when a `float x;` occurs without then being actually initialized to something useful (keep up the great work rikki!), but this particular feature is a special case that is not exactly within scope. And the fact that this is even being added as a special case should be a hint that leaving NaN as the default init is much less useful than some integer-compatible value like 0. P.S. This subject is a bit subjective (no pun intended) but overall we'd likely see more user satisfaction from the float init switch. And from what I could tell, it's been well received by the OpenD folks, so there's already been a bit of a testbed for this.
Aug 13
Floats are default initialized to NaN so people will be coerced to explicitly code what they want the initialized value to be. I've seen enough code where the programmer forgot to initialize a float, it was defaulted to 0, and the wrong result was not detected. ```d float f; // code reviewer: did the programmer intend it to be 0? float g = 0; // code reviewer: yes, the programmer likely meant to initialize it to 0 ``` It's similar to pointers being default initialized to null. Trying to use a null pointer will result in a seg fault. Most people decry this, but it's actually a great feature. If there's a bug in the code, it's better to find it sooner rather than after you ship.
Aug 13
On Friday, 14 August 2026 at 06:38:02 UTC, Walter Bright wrote:Floats are default initialized to NaN so people will be coerced to explicitly code what they want the initialized value to be. I've seen enough code where the programmer forgot to initialize a float, it was defaulted to 0, and the wrong result was notWhy not make it an error, a float that is not explicitly initialized? Would be way better than implicit nan initialization, right?
Aug 14
On Friday, August 14, 2026 1:05:06 AM Mountain Daylight Time Alexandru Ermicioi via Digitalmars-d wrote:On Friday, 14 August 2026 at 06:38:02 UTC, Walter Bright wrote:The language relies on the ability to default-initialize objects. For instance, that's what happens when you allocate a dynamic array or increase its length. There has to be a default value for that to work. It's part of why adding the ability to disable default initialization for structs has been a mess. It's arguably necessary for some contexts, but it means that those structs can't legally be used in any context where default initialization is required. Doing the same to floating point types would be even worse given that they're a built-in type rather than something specific to a particular code base. Also, languages like Java where they make it illegal to use a variable before you give it a value show how problematic it can be to make it an error to not explicitly initialize a variable, because it's pretty easy to get into situations where you know for sure that the variable is given a value before it's used, but the compiler isn't smart enough to figure that out, so you're forced to give it a dummy value just to shut it up. D's approach of having all types have a default value is just cleaner and simpler overall. It does kind of suck with regards to NaN, but the problems with NaN largely exist because NaN exists at all, which goes way beyond the issue of default initialization, and there's no getting around those issues, because NaN is a standard part of IEEE floating point types. - Jonathan M DavisFloats are default initialized to NaN so people will be coerced to explicitly code what they want the initialized value to be. I've seen enough code where the programmer forgot to initialize a float, it was defaulted to 0, and the wrong result was notWhy not make it an error, a float that is not explicitly initialized? Would be way better than implicit nan initialization, right?
Aug 14
On Friday, 14 August 2026 at 08:09:45 UTC, Jonathan M Davis wrote:The language relies on the ability to default-initialize objects. For instance, that's what happens when you allocate a dynamic array or increase its length. There has to be a default value for that to work. It's part of why adding the ability to disable default initialization for structs has been a mess. It's arguably necessary for some contexts, but it means that those structs can't legally be used in any context where default initialization is required. Doing the same to floating point types would be even worse given that they're a built-in type rather than something specific to a particular code base.Right, that would cause mayhem in templated code, an extra static if at minimum.Also, languages like Java where they make it illegal to use a variable before you give it a value show how problematic it can be to make it an error to not explicitly initialize a variable, because it's pretty easy to get into situations where you know for sure that the variable is given a value before it's used, but the compiler isn't smart enough to figure that out, so you're forced to give it a dummy value just to shut it up.Nowadays java compiler seems smarter, it doesn't force you initialize it at declaration site, if all branches after declaration get var initialized before its use.
Aug 14
On Friday, 14 August 2026 at 10:42:16 UTC, Alexandru Ermicioi wrote:On Friday, 14 August 2026 at 08:09:45 UTC, Jonathan M Davis wrote:This is a valid point, but it merely implies that there should be a default initialisation value. It does not imply that this value must be NaN. It's worth noting that the proposed change was implemented in OpenD and there have been very few complaints. If correctness is the goal, the way forward is static analysis, not an "error" value which doesn't actually trigger any sort of error handling or exception.The language relies on the ability to default-initialize objects. For instance, that's what happens when you allocate a dynamic array or increase its length. There has to be a default value for that to work. It's part of why adding the ability to disable default initialization for structs has been a mess. It's arguably necessary for some contexts, but it means that those structs can't legally be used in any context where default initialization is required. Doing the same to floating point types would be even worse given that they're a built-in type rather than something specific to a particular code base.Right, that would cause mayhem in templated code, an extra static if at minimum.
Aug 14
On 8/14/2026 5:48 AM, Indraj Gandham wrote:It's worth noting that the proposed change was implemented in OpenDThat's a mistake.and there have been very few complaints.All it takes is one unintentional default initialization of 0.0 which leads to a subtle bug in your avionics code, banking software, I-beam design, data analysis, etc. And yes, I have seen cases were a linter complained about lack of an initializer on C code, and the maintainer inserted "=0" which closed the issue, but introduced a bug. The idea is to make such bugs OBVIOUS, not subtle.
Aug 14
On Friday, 14 August 2026 at 17:40:20 UTC, Walter Bright wrote:All it takes is one unintentional default initialization of 0.0 which leads to a subtle bug in your avionics code, banking software, I-beam design, data analysis, etc.For graphic applications, it can lead to a minor detail not getting rendered, which in turn can be just as subtle as a math error. The assumption that a single NaN would poison the whole output only holds for numeric calculations where all data is eventually accumulated into one atomic data pool as part of a single (large) formula.The idea is to make such bugs OBVIOUS, not subtle.I suspect that would require SIGNALING NaNs.
Aug 14
On Friday, 14 August 2026 at 17:40:20 UTC, Walter Bright wrote:On 8/14/2026 5:48 AM, Indraj Gandham wrote: And yes, I have seen cases were a linter complained about lack of an initializer on C code, and the maintainer inserted "=0" which closed the issue, but introduced a bug.You haven't solved this problem, the guy who sees an uninitialized float and inserts a zero, will do exactly the same when he sees a default initialized float. He'll lob a zero in, compile and run and see if it's "fixed". Default to NaN doesn't fix that.
Aug 15
On 14/08/2026 10:42 PM, Alexandru Ermicioi wrote:
Also, languages like Java where they make it illegal to use a
variable before you give it a value show how problematic it can be
to make it an error to not explicitly initialize a variable, because
it's pretty easy to get into situations where you know for sure that
the variable is given a value before it's used, but the compiler
isn't smart enough to figure that out, so you're forced to give it a
dummy value just to shut it up.
Nowadays java compiler seems smarter, it doesn't force you initialize it
at declaration site, if all branches after declaration get var
initialized before its use.
This only works without false positives in limited cases.
The moment pointers are involved, loops, or functions it basically error
central.
The fast dfa engine has to ignore any variable that is in a closure
context specifically because it can't be modeled.
Which is a bit of a problem for us, see unreachable code error for why
it isn't a good by default bit of analysis.
Aug 14
On 8/14/2026 3:42 AM, Alexandru Ermicioi wrote:Nowadays java compiler seems smarter, it doesn't force you initialize it at declaration site, if all branches after declaration get var initialized before its use.This requires Data Flow Analysis, which slows the compiler down. It's not a good idea to have the semantics change when turning the optimizer on. Note that when the optimizer is run on D code, any redundant NaN initialization gets removed, so there is no penalty for default initialization. (It's called "Dead Assignment Removal".)
Aug 14
On Friday, 14 August 2026 at 08:09:45 UTC, Jonathan M Davis wrote:On Friday, August 14, 2026 1:05:06 AM Mountain Daylight Time Alexandru Ermicioi via Digitalmars-d wrote:Make it an error where it can be detected, for fields and locals. And make it NaN for expanding arrays. That would be more useful than the current situation.On Friday, 14 August 2026 at 06:38:02 UTC, Walter Bright wrote:The language relies on the ability to default-initialize objects. For instance, that's what happens when you allocate a dynamic array or increase its length.Floats are default initialized to NaN so people will be coerced to explicitly code what they want the initialized value to be. I've seen enough code where the programmer forgot to initialize a float, it was defaulted to 0, and the wrong result was notWhy not make it an error, a float that is not explicitly initialized? Would be way better than implicit nan initialization, right?
Aug 15
On 8/14/2026 12:05 AM, Alexandru Ermicioi wrote:Why not make it an error, a float that is not explicitly initialized? Would be way better than implicit nan initialization, right?Because then you wind up with: ```d float f = 0; // shut up the spurious compiler error message ... initialize(&f); // the actual initialization ``` The 0 initialization is inserted to shut up the compiler, and it will take the reviewer a bit of time wondering why f was initialized to the wrong value. In other words, redundant/vacuous assignments are a code smell. It's a small point, but D is an elegant language, and requiring people to write smelly code is not elegant.
Aug 14
On 15/08/2026 5:26 AM, Walter Bright wrote:On 8/14/2026 12:05 AM, Alexandru Ermicioi wrote:Alternatively make the parameter out: ```d void initialize(out float v); float f; initialize(f); ```Why not make it an error, a float that is not explicitly initialized? Would be way better than implicit nan initialization, right?Because then you wind up with: ```d float f = 0; // shut up the spurious compiler error message ... initialize(&f); // the actual initialization ``` The 0 initialization is inserted to shut up the compiler, and it will take the reviewer a bit of time wondering why f was initialized to the wrong value. In other words, redundant/vacuous assignments are a code smell. It's a small point, but D is an elegant language, and requiring people to write smelly code is not elegant.
Aug 14
On 8/14/2026 10:28 AM, Richard (Rikki) Andrew Cattermole wrote:Alternatively make the parameter out: ```d void initialize(out float v); float f; initialize(f); ````out` will default initialize `v` to NaN upon entry to the function!
Aug 14
On Friday, 14 August 2026 at 17:26:04 UTC, Walter Bright wrote:On 8/14/2026 12:05 AM, Alexandru Ermicioi wrote:And yet that is exactly what you have the compiler doing, inserting a spurious redundant assignment by default, it's just as smelly.Why not make it an error, a float that is not explicitly initialized? Would be way better than implicit nan initialization, right?Because then you wind up with: ```d float f = 0; // shut up the spurious compiler error message ... initialize(&f); // the actual initialization ``` The 0 initialization is inserted to shut up the compiler, and it will take the reviewer a bit of time wondering why f was initialized to the wrong value. In other words, redundant/vacuous assignments are a code smell. It's a small point, but D is an elegant language, and requiring people to write smelly code is not elegant.
Aug 15
On Friday, 14 August 2026 at 17:26:04 UTC, Walter Bright wrote:The 0 initialization is inserted to shut up the compiler, and it will take the reviewer a bit of time wondering why f was initialized to the wrong value.So: Variables must be initialized (1) with the correct initial values (1). If the compiler outputs an error saying "variable not initialized" the programmer will fix this error mechanically (initialize the variable with the first "correct" value that comes to mind, most likely 0.0). If the compiler politely remains silent but initializes the variable with a default value that will most likely lead to an incorrect result, the programmer will notice the bug and be forced to find the correct initial value to fix it. A dirty manipulation :-) ingenious though. What about integers? Why not initialize it with .max? Or some prime number?
Aug 15
On Friday, 14 August 2026 at 06:38:02 UTC, Walter Bright wrote:It's similar to pointers being default initialized to null. Trying to use a null pointer will result in a seg fault.It's not similar at all. There is no sensible init value for a pointer but there is for a float. This change would bring more consistency within D with regard to the behaviour of numeric types. It would also bring D in line with what other languages do (and what most programmers likely expect).Most people decry this, but it's actually a great feature. If there's a bug in the code, it's better to find it sooner rather than after you ship.It's better to find it at compile time and emit a warning, as in Rust. The NaN value silently propagates and is therefore the worst possible choice.
Aug 14
On Friday, 14 August 2026 at 08:17:41 UTC, Indraj Gandham wrote:There is no sensible init value for a pointerThere is, especially for a gc language; theres at least 3 great options new innate last matching type on the stack
Aug 14
On 8/14/2026 1:17 AM, Indraj Gandham wrote:On Friday, 14 August 2026 at 06:38:02 UTC, Walter Bright wrote:I'm afraid we disagree. The null pointer initialization ensures that you cannot dereference an uninitialized pointer and not find out about it. Getting a "NaN" in your program's output is sure to notify the user that there is a BUG in the program. Default initializing to 0.0 runs the high risk of the bug not being noticed.It's similar to pointers being default initialized to null. Trying to use a null pointer will result in a seg fault.It's not similar at all. There is no sensible init value for a pointer but there is for a float.This change would bring more consistency within D with regard to the behaviour of numeric types. It would also bring D in line with what other languages do (and what most programmers likely expect).This is why D is better than other languages.Consider a scientist setting out an array of data collection sensors. If you've got a lot of them, inevitably some will be bad. A bad one should not bring down the whole system. Having the bad data replaced with NaN will mean the rest of your array data will not be corrupted by a stuck-at-zero problem with one sensor.Most people decry this, but it's actually a great feature. If there's a bug in the code, it's better to find it sooner rather than after you ship.It's better to find it at compile time and emit a warning, as in Rust.The NaN value silently propagates and is therefore the worst possible choice.The worst possible choice is the maintainer shutting up the compiler and initializing it to 0.0 without checking what the correct value should be. And you may never realize that this 0.0 propagated into your output. Yes, this happens. I've seen it happen. Having a NaN in your output tells you that your code is broken. A default 0.0 hides bugs.
Aug 14
On Friday, 14 August 2026 at 17:54:25 UTC, Walter Bright wrote:The worst possible choice is the maintainer shutting up the compiler and initializing it to 0.0 without checking what the correct value should be.This is, unironically, a surprisingly accurate description of the average DIP1000 user experience with return ref scope attributes.
Aug 14
On Friday, 14 August 2026 at 17:54:25 UTC, Walter Bright wrote:On 8/14/2026 1:17 AM, Indraj Gandham wrote:It's not a guarantee though is it. NaN is a valid result of some mathematical operations, so an "uninitialized float NaN" could still get lost or hidden. Heck converting a float to integer and the NaN is gone. You need to stop acting like it's foolproof, it's really not. Actually making initialized floats an error would be far more useful.On Friday, 14 August 2026 at 06:38:02 UTC, Walter Bright wrote:I'm afraid we disagree. The null pointer initialization ensures that you cannot dereference an uninitialized pointer and not find out about it. Getting a "NaN" in your program's output is sure to notify the user that there is a BUG in the program. Default initializing to 0.0 runs the high risk of the bug not being noticed.It's similar to pointers being default initialized to null. Trying to use a null pointer will result in a seg fault.It's not similar at all. There is no sensible init value for a pointer but there is for a float.Consider a scientist setting out an array of data collection sensors. If you've got a lot of them, inevitably some will be bad. A bad one should not bring down the whole system. Having the bad data replaced with NaN will mean the rest of your array data will not be corrupted by a stuck-at-zero problem with one sensor.Nonsense. "Data collection sensors" don't use floating point. Why the hell would they add all the silicon overhead of floating point to a sensor IC? They use ints, I've literally never seen a floating point one.99 times out of 100 0.0 is the correct value. So is the 1 time in 100 that NaN helps error early worth the other 99 times you get a NaN nowhere near where it actually comes from? Its not as clear cut as you claim it to be.The NaN value silently propagates and is therefore the worstpossible choice. The worst possible choice is the maintainer shutting up the compiler and initializing it to 0.0 without checking what the correct value should be. And you may never realize that this 0.0 propagated into your output. Yes, this happens. I've seen it happen. Having a NaN in your output tells you that your code is broken. A default 0.0 hides bugs.
Aug 15
On 8/15/2026 3:07 AM, claptrap wrote:You need to stop acting like it's foolproof, it's really not.You are correct that it is not foolproof, but it is far better than 0, because the error is far more likely to be detected.
Aug 19
On Friday, 14 August 2026 at 17:54:25 UTC, Walter Bright wrote:I'm afraid we disagree. The null pointer initialization ensures that you cannot dereference an uninitialized pointer and not find out about it. Getting a "NaN" in your program's output is sure to notify the user that there is a BUG in the program. Default initializing to 0.0 runs the high risk of the bug not being noticed.The difference is that the null ptr will always cause your program to crash when you try to use it. The NaN value will not, and unless your program prints out every float (or you use contracts) it will often be difficult to track down the cause of any resulting strange behaviour. This is the heart of the issue: if you remembered to initialise the float, put in a contract or print the value, you probably also remembered about the default NaN. But if you didn't, it's more likely you wanted 0.0 than NaN. In fact, NaN is almost guaranteed to be incorrect, and it'll appear in the places you least expect.This is why D is better than other languages.D has many facets which make it the best programming language in the world. This is not one of them.Consider a scientist setting out an array of data collection sensors. If you've got a lot of them, inevitably some will be bad. A bad one should not bring down the whole system. Having the bad data replaced with NaN will mean the rest of your array data will not be corrupted by a stuck-at-zero problem with one sensor.This is a contrived example. There are far better, well-understood and widely-known anomaly detection techniques the scientist could leverage to flag (and remove) faulty sensor data before it is processed.The worst possible choice is the maintainer shutting up the compiler and initializing it to 0.0 without checking what the correct value should be. And you may never realize that this 0.0 propagated into your output. Yes, this happens. I've seen it happen.(1) The D compiler does not emit a warning before default NaN initialisation. (2) You're saying it wouldn't be enough anyway, as the user would ignore this imaginary warning and would write `= 0` just to shut it up. It appears you are making the argument that instead of warning the user about incorrect behaviour at compile-time, and instead of inserting the value that the user likely wanted, you are going to make them track down garbage at runtime on the off-chance that they didn't want 0.0 I hope this is a misunderstanding.
Aug 17
On 8/17/2026 5:59 AM, Indraj Gandham wrote:it's more likely you wanted 0.0 than NaN. In fact, NaN is almost guaranteed to be incorrectAnd that is exactly the point of NaN - to be incorrect, and to stand out like a rock in your shoe.D has many facets which make it the best programming language in the world. This is not one of them.Consider the two options: 1. default initialize to 0, because that will be correct most of the time. Never mind if the flight computer says 18,000 gallons of gas is needed to cross the Atlantic, when 20,000 is actually needed. But 18,000 looks good, and you take off, get past the halfway point, and fall out of the sky. 2. default initialize to NaN, and your flight computer says you need NaN gallons of gas, and you turn around and go immediately back to the gate. Option 2 is better when writing professional quality software. --- I googled "software catastrophe caused by incorrect zero initialization" and got: "A software catastrophe caused by incorrect zero initialization often relates to uninitialized memory defaulting to zero unexpectedly, or conversely, a critical variable failing to be zeroed out or handling a zero value improperly (such as a division-by-zero or arithmetic counter rollover). A famous analogue is the September 1997 incident on the guided-missile cruiser USS Yorktown, where a crew member entered a 0 into a database field, causing a division-by-zero collapse across the ship's propulsion network."
Aug 19
On Thursday, 20 August 2026 at 03:36:33 UTC, Walter Bright wrote:On 8/17/2026 5:59 AM, Indraj Gandham wrote:This contrived almost impossible to occur scenario where zero somehow equates to a factor of 2000 which was not caught in testing is not convincing.it's more likely you wanted 0.0 than NaN. In fact, NaN is almost guaranteed to be incorrectAnd that is exactly the point of NaN - to be incorrect, and to stand out like a rock in your shoe.D has many facets which make it the best programming language in the world. This is not one of them.Consider the two options: 1. default initialize to 0, because that will be correct most of the time. Never mind if the flight computer says 18,000 gallons of gas is needed to cross the Atlantic, when 20,000 is actually needed. But 18,000 looks good, and you take off, get past the halfway point, and fall out of the sky.2. default initialize to NaN, and your flight computer says you need NaN gallons of gas, and you turn around and go immediately back to the gate.I can play too: ```d if(gas < amountNeeded) warnPilot(); ``` -Steve
Aug 20
On Friday, 21 August 2026 at 02:36:38 UTC, Steven Schveighoffer wrote:Airplane surgery is very complicated.1. default initialize to 0, because that will be correct most of the time. Never mind if the flight computer says 18,000 gallons of gas is needed to cross the Atlantic, when 20,000 is actually needed. But 18,000 looks good, and you take off, get past the halfway point, and fall out of the sky.This contrived almost impossible to occur scenario where zero somehow equates to a factor of 2000 which was not caught in testing is not convincing.
Aug 20
On Friday, 14 August 2026 at 17:54:25 UTC, Walter Bright wrote:Consider a scientist setting out an array of data collection sensors. If you've got a lot of them, inevitably some will be bad. A bad one should not bring down the whole system. Having the bad data replaced with NaN will mean the rest of your array data will not be corrupted by a stuck-at-zero problem with one sensor.But NaN as default init value is not like a defective sensor distorting the output with bad data. It is like a flawed sensor design always feeding the system with bad data because of a design failure in its circuitry.
Aug 17
On Friday, 14 August 2026 at 06:38:02 UTC, Walter Bright wrote:Floats are default initialized to NaN so people will be coerced to explicitly code what they want the initialized value to be. I've seen enough code where the programmer forgot to initialize a float, it was defaulted to 0, and the wrong result was not detected. ```d float f; // code reviewer: did the programmer intend it to be 0? float g = 0; // code reviewer: yes, the programmer likely meant to initialize it to 0 ``` It's similar to pointers being default initialized to null. Trying to use a null pointer will result in a seg fault. Most people decry this, but it's actually a great feature. If there's a bug in the code, it's better to find it sooner rather than after you ship.Hi Walter, I really appreciate the response, however I think that all the points I wrote were unaddressed (I mentioned the comparison with null pointers and why it is my opinion that it is a false equivalence as well). Nevertheless, the topic is relatively low importance to me and I'm okay with just using a linter to remind myself to explicitly initialize the floats. I just figured the change would be an easy QOL improvement for most users. With regards to erroring if they're not initialized, that would be a very good alternative to 0 init as well (I mentioned that too).
Aug 14
On 14/08/2026 8:19 PM, ABrightLight wrote:On Friday, 14 August 2026 at 06:38:02 UTC, Walter Bright wrote:Unfortunately this is a good example of Walter leaving out the analysis, and skipping to the conclusion. I spend a good chunk of my time figuring out what the analysis was lol. NaN's come in two flavors, signaling and non-signaling. Originally D default initialized floats to signal, but that was changed as it was producing an inconsistency that was a problem (I wasn't involved with this). If you try to do math on a signaling NaN it will throw a hardware exception, just like doing a null dereference does. A non-signaling NaN is good, because you can at least detect when something has gone wrong, just not the source. Silent corruption is always worse than detectable corruption.Floats are default initialized to NaN so people will be coerced to explicitly code what they want the initialized value to be. I've seen enough code where the programmer forgot to initialize a float, it was defaulted to 0, and the wrong result was not detected. ```d float f; // code reviewer: did the programmer intend it to be 0? float g = 0; // code reviewer: yes, the programmer likely meant to initialize it to 0 ``` It's similar to pointers being default initialized to null. Trying to use a null pointer will result in a seg fault. Most people decry this, but it's actually a great feature. If there's a bug in the code, it's better to find it sooner rather than after you ship.Hi Walter, I really appreciate the response, however I think that all the points I wrote were unaddressed (I mentioned the comparison with null pointers and why it is my opinion that it is a false equivalence as well).Nevertheless, the topic is relatively low importance to me and I'm okay with just using a linter to remind myself to explicitly initialize the floats. I just figured the change would be an easy QOL improvement for most users.https://forum.dlang.org/thread/tcfqveygmebplsgmexgr forum.dlang.org
Aug 14
On 8/14/2026 7:02 AM, Richard (Rikki) Andrew Cattermole wrote:NaN's come in two flavors, signaling and non-signaling. Originally D default initialized floats to signal, but that was changed as it was producing an inconsistency that was a problem (I wasn't involved with this).Signalling NaNs simply did not work unless you wrote your code in assembler. That's because the compiler itself would flip it to a quiet nan every time it was copied.If you try to do math on a signaling NaN it will throw a hardware exception, just like doing a null dereference does.No compiler I know implements this, because it's a nuisance. NaNs were invented for the 8087, and while it made sense on paper, in practice it didn't work out too well.A non-signaling NaN is good, because you can at least detect when something has gone wrong, just not the source. Silent corruption is always worse than detectable corruption.We can agree on that!
Aug 14
On 15/08/2026 9:28 AM, Walter Bright wrote:
A non-signaling NaN is good, because you can at least detect when
something has gone wrong, just not the source.
Silent corruption is always worse than detectable corruption.
We can agree on that!
The only thing you and I disagree on for NaN's is how much static
analysis to throw at it.
Personally I'm all for throwing full soundness at it!
Aug 14
On Friday, 14 August 2026 at 21:28:54 UTC, Walter Bright wrote:On 8/14/2026 7:02 AM, Richard (Rikki) Andrew Cattermole wrote:The old Delphi compiler did, backing the 2000s, no idea if it still does. But you did have to be careful interfacing with external code, like calling C++ dll you had to make sure to switch it off and back on again. It was actually pretty useful from what i remember.If you try to do math on a signaling NaN it will throw a hardware exception, just like doing a null dereference does.No compiler I know implements this, because it's a nuisance. NaNs were invented for the 8087, and while it made sense on paper, in practice it didn't work out too well.
Aug 15
On 8/14/2026 1:19 AM, ABrightLight wrote:Hi Walter, I really appreciate the response, however I think that all the points I wrote were unaddressed (I mentioned the comparison with null pointers and why it is my opinion that it is a false equivalence as well).My opinion is it is a reasonable equivalence! Both are meant to make errors visible.With regards to erroring if they're not initialized, that would be a very good alternative to 0 init as well (I mentioned that too).I responded to that multiple times :-/
Aug 14
On Friday, 14 August 2026 at 21:24:36 UTC, Walter Bright wrote:On 8/14/2026 1:19 AM, ABrightLight wrote:recently trump said "house prices should go up"; that may in fact be `a response` but perhaps some people may feel `unaddressed`Hi Walter, I really appreciate the response, however I think that all the points I wrote were unaddressed (I mentioned the comparison with null pointers and why it is my opinion that it is a false equivalence as well).My opinion is it is a reasonable equivalence! Both are meant to make errors visible.With regards to erroring if they're not initialized, that would be a very good alternative to 0 init as well (I mentioned that too).I responded to that multiple times :-/
Aug 14
On Friday, 14 August 2026 at 06:38:02 UTC, Walter Bright wrote:Floats are default initialized to NaN so people will be coerced to explicitly code what they want the initialized value to be. I've seen enough code where the programmer forgot to initialize a float, it was defaulted to 0, and the wrong result was not detected. ```d float f; // code reviewer: did the programmer intend it to be 0? float g = 0; // code reviewer: yes, the programmer likely meant to initialize it to 0 ```D advocates for unittest -> what happen to it? Same as int i; // There is no different than float -> be consistent Happy Coding!
Aug 14
On Friday, 14 August 2026 at 06:38:02 UTC, Walter Bright wrote:Floats are default initialized to NaN so people will be coerced to explicitly code what they want the initialized value to be.Maybe the next D Edition could require initialization of types that don’t initialize with a value equal to `0`. D’s behavior with these is annoying, because leads to needless debug sessions, and also surprising because no other language that D is similar Essentially, character and floating-point types should behave like structs with ` disable this()`. Of course, as I said, that would be for the next Edition because it would break code. I don’t know how much existing D code really uses those initializers, probably some, but very little, because the defaults are quite useless, intentionally so.
Aug 17
On 18/08/2026 2:03 AM, Quirin Schroll wrote:On Friday, 14 August 2026 at 06:38:02 UTC, Walter Bright wrote:Just keep in mind that this cannot cover all cases, like heap allocations.Floats are default initialized to NaN so people will be coerced to explicitly code what they want the initialized value to be.Maybe the next D Edition could require initialization of types that don’t initialize with a value equal to `0`. D’s behavior with these is annoying, because leads to needless debug sessions, and also surprising Java all default-initialize to `0`. Essentially, character and floating- point types should behave like structs with ` disable this()`. Of course, as I said, that would be for the next Edition because it would break code. I don’t know how much existing D code really uses those initializers, probably some, but very little, because the defaults are quite useless, intentionally so.
Aug 17
On Monday, 17 August 2026 at 14:03:46 UTC, Quirin Schroll wrote:On Friday, 14 August 2026 at 06:38:02 UTC, Walter Bright wrote:I don't think it's wise to change, it'll cause too much friction and inconsistency in documentation, however, I think there is something that could be done as a compromise. extern(C) struct was rejected, so perhaps a ` pod struct` that ensures 0 init would be better? 0 init has the advantage of producing tiny executable, so there are still some valid reason to have them.Floats are default initialized to NaN so people will be coerced to explicitly code what they want the initialized value to be.Maybe the next D Edition could require initialization of types that don’t initialize with a value equal to `0`. D’s behavior with these is annoying, because leads to needless debug sessions, and also surprising because no other language that D default-initialize to `0`. Essentially, character and floating-point types should behave like structs with ` disable this()`. Of course, as I said, that would be for the next Edition because it would break code. I don’t know how much existing D code really uses those initializers, probably some, but very little, because the defaults are quite useless, intentionally so.
Aug 17
On Monday, 17 August 2026 at 14:16:58 UTC, libxmoc wrote:0 init has the advantage of producing tiny executable, so there are still some valid reason to have them.This is actually what put me over the edge on making the change in opend. I'm basically on the fence, nan and 0 have pros and cons, but this is a little advantage. My blog about it btw: https://dpldocs.info/this-week-in-arsd/Blog.Posted_2025_09_29.html#float-and-char-init
Aug 17
On 8/17/2026 7:16 AM, libxmoc wrote:C and C++ still do not default initialize stack variables to anything other than garbage. before explicitly assigning a value, you get an error. (It's extremely difficult to track down an uninitialized variable in C and C++, because every change you make to the program to try and track it down, changes the values in it.)and also surprising because no other default-initialize to `0`.
Aug 17
On 18/08/2026 3:15 PM, Walter Bright wrote:(It's extremely difficult to track down an uninitialized variable in C and C++, because every change you make to the program to try and track it down, changes the values in it.)-preview=fastdfa says otherwise. So many of the C tests fail due to this :)
Aug 17
On Monday, 17 August 2026 at 14:03:46 UTC, Quirin Schroll wrote:Maybe the next D Edition could require initialization of types that don’t initialize with a value equal to `0`. D’s behavior with these is annoying, because leads to needless debug sessions, and also surprising because no other language that D default-initialize to `0`. Essentially, character and floating-point types should behave like structs with ` disable this()`. Of course, as I said, that would be for the next Edition because it would break code. I don’t know how much existing D code really uses those initializers, probably some, but very little, because the defaults are quite useless, intentionally so.Very little code would be impacted, as shown by OpenD's successful change from NaN to 0.0, a small QoL improvement which could be implemented in upstream today (but won't be).
Aug 17
On Monday, 17 August 2026 at 14:43:00 UTC, Indraj Gandham wrote:[snip] Very little code would be impacted, as shown by OpenD's successful change from NaN to 0.0, a small QoL improvement which could be implemented in upstream today (but won't be)."Small QoL improvement...could be implemented in upstream today" that would also potentially break code. This is what editions are for.
Aug 17
On Monday, 17 August 2026 at 18:23:32 UTC, jmh530 wrote:"Small QoL improvement...could be implemented in upstream today" that would also potentially break code. This is what editions are for.You are referring to this change as if it is a hypothetical. In reality, it has already been done and the extent of the (limited) breakage has been assessed. See the link in adr's post for details.
Aug 17
On Monday, 17 August 2026 at 20:20:23 UTC, Indraj Gandham wrote:You are referring to this change as if it is a hypothetical. In reality, it has already been done and the extent of the (limited) breakage has been assessed. See the link in adr's post for details.Don't forget that OpenD has limited usage as well. And even though Adam's code base may be big - it is mostly written by Adam (with his habits). Upstream D may have much wider variety of code design usages.
Aug 17
On Monday, 17 August 2026 at 21:35:35 UTC, Sergey wrote:On Monday, 17 August 2026 at 20:20:23 UTC, Indraj Gandham wrote::spray_bottle: "You are referring to this change as if it is a hypothetical."You are referring to this change as if it is a hypothetical. In reality, it has already been done and the extent of the (limited) breakage has been assessed. See the link in adr's post for details.Don't forget that OpenD has limited usage as well. And even though Adam's code base may be big - it is mostly written by Adam (with his habits). Upstream D may have much wider variety of code design usages.
Aug 17
On Monday, 17 August 2026 at 18:23:32 UTC, jmh530 wrote:"Small QoL improvement...could be implemented in upstream today" that would also potentially break code. This is what editions are for.My understanding is that an older edition will eventually stop being supported, and that the intent is at some point for old code to be ported to a newer edition if it needs to compile with a newer compiler. Changing `float.init` could cause errors that can only be detected at runtime, perhaps in some very rare combination of runtime events. I don't think D should (ab)use editions to silently break the runtime behaviour of code that was correct in an earlier version.
Aug 17
On Monday, 17 August 2026 at 20:50:39 UTC, Nick Treleaven wrote:My understanding is that an older edition will eventually stop being supported, and that the intent is at some point for old code to be ported to a newer edition if it needs to compile with a newer compiler.I don't think we are supposed to stop supporting any specific editions. That would defeat the purpose. -Steve
Aug 17
On 18/08/2026 2:36 PM, Steven Schveighoffer wrote:On Monday, 17 August 2026 at 20:50:39 UTC, Nick Treleaven wrote:Eventually we will, but it'll be like 20+ years.My understanding is that an older edition will eventually stop being supported, and that the intent is at some point for old code to be ported to a newer edition if it needs to compile with a newer compiler.I don't think we are supposed to stop supporting any specific editions. That would defeat the purpose. -Steve
Aug 17
On Tuesday, 18 August 2026 at 02:36:59 UTC, Steven Schveighoffer wrote:On Monday, 17 August 2026 at 20:50:39 UTC, Nick Treleaven wrote:Even if that were true, it should not be unreasonably hard to port old code to a newer edition.My understanding is that an older edition will eventually stop being supported, and that the intent is at some point for old code to be ported to a newer edition if it needs to compile with a newer compiler.I don't think we are supposed to stop supporting any specific editions. That would defeat the purpose.
Aug 19
On Monday, 17 August 2026 at 14:03:46 UTC, Quirin Schroll wrote:On Friday, 14 August 2026 at 06:38:02 UTC, Walter Bright wrote:When done well (like in Haskell or Rust) I also think the best default values are no default values. But that requires it's easy to avoid declaring variables before there are valid values for them. IMO it isn't the case in D. The language is imperative at its root so there are often cases where you want to declare a variable before initialising it. It is almost always possible to avoid doing so if you're dogged about it, but the cure tends to get worse at times than the disease. D-style "paranoid" default values are the best option IMO - at least for mundane types - when language ergonomics would suffer without them. If, with help of future language features, we can comprehensively avoid relying the default values some day without kludgy tricks, then it's time to do what you suggest.Floats are default initialized to NaN so people will be coerced to explicitly code what they want the initialized value to be.Maybe the next D Edition could require initialization of types that don’t initialize with a value equal to `0`. D’s behavior with these is annoying, because leads to needless debug sessions, and also surprising because no other language that D default-initialize to `0`. Essentially, character and floating-point types should behave like structs with ` disable this()`.
Aug 17
On 8/17/2026 7:03 AM, Quirin Schroll wrote:Maybe the next D Edition could require initialization of types that don’t initialize with a value equal to `0`. D’s behavior with these is annoying, because leads to needless debug sessions, and also surprising because no other default-initialize to `0`.My reply to this seems to have disappeared. C and C++ default initialize locals to garbage, not zero. initializations.
Aug 19
On Wednesday, 19 August 2026 at 07:31:14 UTC, Walter Bright wrote:On 8/17/2026 7:03 AM, Quirin Schroll wrote:C++: ```cpp float x{}; // x == 0.0f float y = {}; // y == 0.0f struct Foo { float value{}; // automatically initialized to 0.0f }; ```Maybe the next D Edition could require initialization of types that don’t initialize with a value equal to `0`. D’s behavior with these is annoying, because leads to needless debug sessions, and also surprising because no other language that D default-initialize to `0`.My reply to this seems to have disappeared. C and C++ default initialize locals to garbage, not zero.explicit initializations.```csharp class Foo { float value; // automatically 0f float[] values = new float[100]; // all 0f } ```
Aug 19
On Wednesday, 19 August 2026 at 07:42:00 UTC, Serg Gini wrote:On Wednesday, 19 August 2026 at 07:31:14 UTC, Walter Bright wrote:I think that your answer is a bit out-of-topic. We started on "default init" (implicit value expected) but here you show something that's more about "explicit init". That eventually falls back on a talk of a D language friend, IIRC, the Salt Lake City edition.On 8/17/2026 7:03 AM, Quirin Schroll wrote:C++: ```cpp float x{}; // x == 0.0f float y = {}; // y == 0.0f struct Foo { float value{}; // automatically initialized to 0.0f }; ```Maybe the next D Edition could require initialization of types that don’t initialize with a value equal to `0`. D’s behavior with these is annoying, because leads to needless debug sessions, and also surprising because no other language default-initialize to `0`.My reply to this seems to have disappeared. C and C++ default initialize locals to garbage, not zero.explicit initializations.```csharp class Foo { float value; // automatically 0f float[] values = new float[100]; // all 0f } ```
Aug 19
On Wednesday, 19 August 2026 at 09:33:21 UTC, user1234 wrote:On Wednesday, 19 August 2026 at 07:42:00 UTC, Serg Gini wrote:[...]On Wednesday, 19 August 2026 at 07:31:14 UTC, Walter Bright wrote:On 8/17/2026 7:03 AM, Quirin Schroll wrote:I think that your answer is a bit out-of-topic. We started on "default init" (implicit value expected) but here you show something that's more about "explicit init". That eventually falls back on a talk of a D language friend, IIRC, the Salt Lake City edition.sorry about the little inacuraccy, I was refering to Scott Meyers which was invited in Berlin edition 2017.
Aug 19
On Wednesday, 19 August 2026 at 07:42:00 UTC, Serg Gini wrote:
```csharp
class Foo
{
float value; // automatically 0f
float[] values = new float[100]; // all 0f
}
```
D:
```d
void main() {
float[int] aa;
aa[0]++;
writeln(a[0]); // ???
}
```
-Steve
Aug 19
On Wednesday, 19 August 2026 at 20:58:56 UTC, Steven
Schveighoffer wrote:
D:
```d
void main() {
float[int] aa;
aa[0]++;
writeln(a[0]); // ???
}
```
-Steve
1 :)
Aug 19
On Friday, 14 August 2026 at 06:38:02 UTC, Walter Bright wrote:Floats are default initialized to NaN so people will be coerced to explicitly code what they want the initialized value to be. I've seen enough code where the programmer forgot to initialize a float, it was defaulted to 0, and the wrong result was not detected. ```d float f; // code reviewer: did the programmer intend it to be 0? float g = 0; // code reviewer: yes, the programmer likely meant to initialize it to 0 ``` It's similar to pointers being default initialized to null. Trying to use a null pointer will result in a seg fault. Most people decry this, but it's actually a great feature. If there's a bug in the code, it's better to find it sooner rather than after you ship.It's helped me more than a handful of times when building a linear algebra math library to always explicitly initialize floating point values and never assume zero. I like NaN because the error propogates, it's very easy to detect and then debug NaN versus a garbage value which can sneak by. floating point numbers being initialized to NaN is a good reminder that while they're 'grouped' and often taught as 'a primitive type' -- they behave differently (i.e. drift error, can't represent everything, need to be compared carefully, etc.)!
Aug 17
On 14/08/2026 5:57 PM, ABrightLight wrote:Hello. I understand this subject's been discussed a number of times before, but I'd like to throw in my reasoning for why it would benefit us more for floats to initialize to 0 than NaN. 1. float is generally used for numeric computation (things like NaN boxing are examples of uses outside of this) and as such have similarity to the integer types (they will even implicitly coerce mathematical operations to float). Since integers default to 0, floats should too. 1a. It may be argued that integers only default to 0 because there is no meaningful "null" value, but in my opinion this is not convincing because I think that most people would opt for them getting a reasonable default value right from the start instead of being forced to `= 0;` It is very common to see loop variables and other forms just say `int i;` or similar, and no one is confused by this. 2. It is argued that since, like pointers that have `null` and are default initialized to this, floats should also initialize to its version of `null`. However this is a false equivalence since the use of a null pointer is specified/standardized to crash the program due to a concern for memory safety (it's not even set to undefined behavior, a program halt must occur). The same memory safety concern is not present for most operations relying on floats, and the existence of NaN being left without a crash [or even an exception thrown] is to cater to performance. For cases where debugging by program halt is required, most of the time the approach done is for a compiler switch to allow throwing an exception instead of just halting the program, since a stack trace is presumed to be desired.I mentioned this else where, the reason it doesn't cause a hardware exception was a decision that D made, as it had bad interactions. The CPU can do it.3. I know that rikki's DFA implementation will be able to detect when a `float x;` occurs without then being actually initialized to something useful (keep up the great work rikki!), but this particular feature is a special case that is not exactly within scope. And the fact that this is even being added as a special case should be a hint that leaving NaN as the default init is much less useful than some integer-compatible value like 0.Thanks. It is based upon preventing uninitialized variable reads. The main difference is it has been special cased so only a mathematical operation will trigger it. Other reads like returning it, won't. This is to prevent false positives, but could be changed if so desired.
Aug 14
Another problem with NaN signalling an exception is no longer having a value to be used for a bad pixel in your satellite's camera.
Aug 14
On Friday, 14 August 2026 at 05:57:55 UTC, ABrightLight wrote:Hello. I understand this subject's been discussed a number of times before, but I'd like to throw in my reasoning for why it would benefit us more for floats to initialize to 0 than NaN.I'm in the `float.init = 0` team only because I know most people prefer the default to be `float.init = 0`. Arguments like "defining errors out of existence" or that NaN silently propagates are missing the point of NaN or what the main issue here really is. What is the main issue? It's who is going to write five extra characters. ```d float a = 0.0f; // Zero fans :( float a = float.nan // NaN fans :( ``` I never care about the default float value because I usually write: ```d auto number = 0.0f ``` No issue. I defined the error out of existence! Feels good to say that line. Only issue remaining are structs and generic code. Those two I get that it might be annoying to set default values only for floats.
Aug 14
On 8/14/2026 9:23 AM, Kapendev wrote:Only issue remaining are structs and generic code. Those two I get that it might be annoying to set default values only for floats.You can set a default value for struct fields like this: ```d struct S { int a = 7; } S s; assert(s.a == 7); ``` Perfectamundo!
Aug 14
On Friday, 14 August 2026 at 05:57:55 UTC, ABrightLight wrote:Hello. I understand this subject's been discussed a number of times before, but I'd like to throw in my reasoning for why it would benefit us more for floats to initialize to 0 than NaN.In all the years I have used D, whenever I have forgotten to initialize a floating point number, the fix was ALWAYS to initialize explicitly to 0, because that's what I expected and desired to happen. This is a big stain on D, and it disrupts everyone's work unnecessarily. The problem is the distance from the error to the result. I don't ever expect it to change. -Steve
Aug 14
Ada was developed to be a safe language before NaNs existed. Being curious, I googled what Ada did with default initialization: "Ada does not automatically default initialize standalone floating-point variables (or other scalar types) to a specific value like 0.0. If you declare a floating-point variable without an explicit initialization expression, its value is uninitialized, and reading it before assigning a value is erroneous behavior." and: "Compilers like GNAT provide pragmas (such as Initialize_Scalars) or specific command-line flags during development to fill uninitialized scalar variables with invalid or abnormal values. This helps catch uninitialized variable bugs early via constraint checks rather than relying on an accidental default zero." and: "While standard Fortran does not enforce this by default, many legacy and modern Fortran compilers (such as gfortran) include specific compiler options like -finit-real=nan. This instructs the compiler to initialize all unallocated or undefined real variables to a Signaling NaN (sNaN)." Looks like I'm not the only one advocating this for bug reduction. Some outside opinions: https://stackoverflow.com/questions/1036686/is-it-a-good-idea-to-use-ieee754-floating-point-nan-for-values-which-are-not-set
Aug 14
On Saturday, 15 August 2026 at 04:42:24 UTC, Walter Bright wrote:Some outside opinions: https://stackoverflow.com/questions/1036686/is-it-a-good-idea-to-use-ieee754-floating-point-nan-for-values-which-are-not-setWe dont care about outsider theory, our **repeated** *personal* **experience** is that nan passed to a graphics api is a no op and its one of the slowest thing to debug. adr ran into it on camera, steve-l guy teachs kids raylib and sees the repeat again and again, etc etc etc etc C dev's reading a spec and dreaming has less evidential weight then a new programmer running into this once.
Aug 15
On Saturday, 15 August 2026 at 13:28:42 UTC, monkyyy wrote:On Saturday, 15 August 2026 at 04:42:24 UTC, Walter Bright wrote:I agree with this guy 👆🙏Some outside opinions: https://stackoverflow.com/questions/1036686/is-it-a-good-idea-to-use-ieee754-floating-point-nan-for-values-which-are-not-setWe dont care about outsider theory, our **repeated** *personal* **experience** is that nan passed to a graphics api is a no op and its one of the slowest thing to debug. adr ran into it on camera, steve-l guy teachs kids raylib and sees the repeat again and again, etc etc etc etc C dev's reading a spec and dreaming has less evidential weight then a new programmer running into this once.
Aug 15
On Saturday, 15 August 2026 at 13:28:42 UTC, monkyyy wrote:a new programmer running into this once.Let them who has run into this only once cast the first stone.
Aug 15
On 8/15/2026 6:28 AM, monkyyy wrote:On Saturday, 15 August 2026 at 04:42:24 UTC, Walter Bright wrote:Sorry you had a bad initial experience with this. Default initialization is not the only way a NaN can be appear in floating point: https://en.wikipedia.org/wiki/NaN#Operations_generating_NaN There's no getting away from dealing with NaNs. Default initialization to zero is not going to make that go away. The std.math functions are all carefully crafted to correctly deal with NaNs. As for the graphics case, what happened is the error showed itself immediately, which is much better than having a subtle unintended 0 initialization that may go undetected for years. BTW, I like it when checking in a piece of code, and then the test suite promptly fails. To find the problem, I use a binary search on the PR to find out where the source is. This can be automated by using Dustmite: https://blog.dlang.org/archive/2020/04/13/dustmite-the-general-purpose-data-reduction-tool/Some outside opinions: https://stackoverflow.com/questions/1036686/is-it-a-good-idea-to-use-ieee754-floating-point-nan-for-values-which-are-not-setWe dont care about outsider theory, our **repeated** *personal* **experience** is that nan passed to a graphics api is a no op and its one of the slowest thing to debug. adr ran into it on camera, steve-l guy teachs kids raylib and sees the repeat again and again, etc etc etc etcC dev's reading a spec and dreaming has less evidential weight then a new programmer running into this once.New programmers need to learn about NaN anyway. There's no reason to believe that a 0.0 is always correct, and debugging it will be a lot harder.
Aug 15
On Saturday, 15 August 2026 at 22:48:11 UTC, Walter Bright wrote:As for the graphics case, what happened is the error showed itself immediately, which is much better than having a subtle unintended 0 initialization that may go undetected for years.The intended initialization is 0 the vast majority of the timeThere's no getting away from dealing with NaNs. Default initialization to zero is not going to make that go away. The std.math functions are all carefully crafted to correctly deal with NaNs.false 0's are not unnoticeable they render at the origin or as pure black and I generally need to rewrite all math functions to *not* be nan friendly because nan propagating is a problem. Your just asserting terrible takes for video games, cause they aint airplane surgery. Failures that do something are amusing; doing nothing is very bad and all the c libs treat nan as a rareish value cause in c their data structures 0 initialize. There more a video game community then dlang airplane surgery companies.
Aug 15
On 8/15/2026 7:16 PM, monkyyy wrote:The intended initialization is 0 the vast majority of the timeYes, you are correct.their data structures 0 initialize.Use this for data structures: ```d struct S { float f = 0; // initializes struct to 0 } float[100] a = 0; // initializes array to 0 ``` Use calloc() to allocate memory for data structures.
Aug 19
On Thursday, 20 August 2026 at 04:02:47 UTC, Walter Bright wrote:
```d
struct S {
float f = 0; // initializes struct to 0
}
float[100] a = 0; // initializes array to 0
```
I dont use a linter, your asking me to remember to do that every
single time; I dont.
Using your own agrument for auto initialization for everything
else, this violates that. Your anti-initializing floats.
Aug 20
On Thursday, 20 August 2026 at 12:46:30 UTC, monkyyy wrote:On Thursday, 20 August 2026 at 04:02:47 UTC, Walter Bright wrote:Happy ending. ```d struct S { float f = 0; // initializes struct to 0 } float[100] a = 0; // initializes array to 0 ```I dont use a linter, your asking me to remember to do that every single time; I dont. Using your own agrument for auto initialization for everything else, this violates that. Your anti-initializing floats.
Aug 20
On Sunday, 16 August 2026 at 02:16:22 UTC, monkyyy wrote:Your just asserting terrible takes for video gamesAs a junior PHP web dev, I support NaN and don't support video games.
Aug 20
On 8/14/2026 2:25 PM, Steven Schveighoffer wrote:In all the years I have used D, whenever I have forgotten to initialize a floating point number, the fix was ALWAYS to initialize explicitly to 0, because that's what I expected and desired to happen.Yes, initializing to 0.0 is very common. And that works fine until the correct initialization is 0.001, and there's an unrecognized bug in the output.This is a big stain on D, and it disrupts everyone's work unnecessarily. The problem is the distance from the error to the result.The problem with default initialization to 0.0 is not recognizing that the result is in error, which I submit is much much worse. It costs orders of magnitude less money to fix a bug made very visible with a NaN output than output that is just slightly wrong and unnoticed out in the field. When reviewing code, and you see: ```d float f; ``` is the intention to initialize it to zero, or did the programmer simply forget to initialize it? I've had more than enough of the latter in actual code. P.S. In case it isn't obvious, this derives from my experience designing flight controls for the 757. You really really really want to find all the bugs before cutting metal or, heaven forbid, trying to lift it off the runway. Inconvenience be damned.
Aug 14
I guess it depends upon the use case. In my experience with mostly developing 3D apps and game code etc I have only ever wanted the default to be 0. I have had bad experiences with the nan default. One time it caused a massive slow down which delayed me for ages trying to understand what was causing the problem. I just assumed for a while that D was just slow. Other times it caused weird visual artifacts or incorrect rendering for no obvious reason.When reviewing code, and you see: ```d float f; ```For what I do the above example is not the common problem. This is usually pretty easy to see either as a local or a global. My problem is when using a struct with a float I would generally assume that the float would be initialised to 0 (this is what C/C++ does for example and copying code examples from the web will have some C code such as: ``` typedef struct VkClearDepthStencilValue { float depth; uint32_t stencil; } VkClearDepthStencilValue; VkClearDepthStencilValue depthStencilClear = { .stencil = 0 }; or VkClearDepthStencilValue depthStencilClear = {0}; ``` I would assume the D equivalent would produce the same result because of course everything would just be zeroed by default :) ``` VkClearDepthStencilValue depthStencilClear; ``` No this produces a bug that is unexpected and may not be trivial to track down. I do understand the reasoning for defaulting to nan though. It is just that I have always wanted and expected it to be 0. I do love using D btw but this is one of the small quirks that usually I remember to work around :)
Aug 15
On 8/15/2026 3:13 AM, pete wrote:
typedef struct VkClearDepthStencilValue {
float depth = 0;
uint32_t stencil;
} VkClearDepthStencilValue;
will default initialize .depth to 0.0. May I suggest doing a grep across your
C++ derived declarations looking for floats and doubles.
BTW, C and C++ will default initialize all variables to garbage when they are
declared as a function local! Those are very hard to track down. I once spent 3
days trying to track one down. It scarred me for life.
Aug 15
On Sunday, 16 August 2026 at 02:00:29 UTC, Walter Bright wrote:On 8/15/2026 3:13 AM, pete wrote:I usually do this now but I occasionally forget and it would not be obvious to someone who hadn't already been bitten by the problem in the first place. Most people would assume the default would just be zero and if you are going to violate the principle of least surprise by making it different then the result of using the nan should be immediate and obvious. If it worked like a null pointer dereference then it would make sense because they are easy to track down. The default nan is just the compiler working behind your back inserting poison. Then when you run it things just "don't work right" in non obvious ways and you either (1) leave it thinking you're just having a bad day at the keyboard or (2) debug the whole thing to see where the data deviates from what you expected and (2a) curse loudly when you realise what the compiler just did to you :)typedef struct VkClearDepthStencilValue { float depth = 0; uint32_t stencil; } VkClearDepthStencilValue;will default initialize .depth to 0.0. May I suggest doing a grep across your C++ derived declarations looking for floats and doubles.
Aug 16
On 8/16/2026 1:32 AM, pete wrote:Most people would assume the default would just be zero and if you are going to violate the principle of least surprise by making it different then the result of using the nan should be immediate and obvious.If 0.0 is the wrong initialization, then it is worse trying to detect the error. For example, 0.001 + 0.0 => 0.001 => overlooked error 0.001 + NaN => NaN => obvious error
Aug 18
On Tuesday, 18 August 2026 at 19:16:36 UTC, Walter Bright wrote:0.001 + 0.0 => 0.001 => overlooked errorThe point of floats is to be pretend analog signals, handling small errors is fundamental to the type theory, your using floats because you have a continuous fuzzy decision. You take several of small decisions like a solar system of gravity vectors and sum them. Nan breaks this workflow because ops, everything is now nan.
Aug 18
On 8/18/2026 12:47 PM, monkyyy wrote:The point of floats is to be pretend analog signals, handling small errors is fundamental to the type theory, your using floats because you have a continuous fuzzy decision. You take several of small decisions like a solar system of gravity vectors and sum them. Nan breaks this workflow because ops, everything is now nan.The purpose of NaN is to expose errors, not hide them.
Aug 18
On Sunday, 16 August 2026 at 02:00:29 UTC, Walter Bright wrote:BTW, C and C++ will default initialize all variables to garbage when they are declared as a function local! Those are very hard to track down. I once spent 3 days trying to track one down. It scarred me for life.I think we should stop comparing with 50 years old languages. The bar is too low. I've checked what modern system languages are doing: Mojo, Swift, Zig and Rust are not allowing to declare uninitialized float. Go is making it 0.0
Aug 17
On Monday, 17 August 2026 at 07:52:21 UTC, Serg Gini wrote:On Sunday, 16 August 2026 at 02:00:29 UTC, Walter Bright wrote:The main issue is `float.init`. Once you disallow implicit initialization, you need a way to express explicit initialization in templates. Any non trivial template will end up with something like `T tmp = T.init;` And if T is float, you are at square one, you get a silent NaN. Dlang shines when it takes proven things and makes them ergonomic (templates), when it tackle a problem and make it braindead trivial (metaprograming). But once it tries to "be different", even for the sake of correctness, it often fails. JurajBTW, C and C++ will default initialize all variables to garbage when they are declared as a function local! Those are very hard to track down. I once spent 3 days trying to track one down. It scarred me for life.I think we should stop comparing with 50 years old languages. The bar is too low. I've checked what modern system languages are doing: Mojo, Swift, Zig and Rust are not allowing to declare uninitialized float. Go is making it 0.0
Aug 17
On 8/15/2026 3:13 AM, pete wrote:
(this is what C/C++ does for example and copying code examples from the web
will have some C code such as:
```
typedef struct VkClearDepthStencilValue {
float depth;
uint32_t stencil;
} VkClearDepthStencilValue;
VkClearDepthStencilValue depthStencilClear = {
.stencil = 0
};
If you leave it as a C file, and then import it using Import C, the default
initializer for `.depth` with be 0.0. (!!)
Aug 15
On Sunday, 16 August 2026 at 02:33:42 UTC, Walter Bright wrote:On 8/15/2026 3:13 AM, pete wrote:Would scoping 0 initialization to extern(C) struct (or under -betterC) make sense as a compromise?(this is what C/C++ does for example and copying code examples from the web will have some C code such as: ``` typedef struct VkClearDepthStencilValue { float depth; uint32_t stencil; } VkClearDepthStencilValue; VkClearDepthStencilValue depthStencilClear = { .stencil = 0 };If you leave it as a C file, and then import it using Import C, the default initializer for `.depth` with be 0.0. (!!)
Aug 16
On 8/16/2026 1:30 AM, libxmoc wrote:Would scoping 0 initialization to extern(C) struct (or under -betterC) make sense as a compromise?It would break the language into two incompatible dialects. extern(C) is not for semantic differences, it is just to match C calling conventions.
Aug 16
On 17/08/2026 3:48 PM, Walter Bright wrote:On 8/16/2026 1:30 AM, libxmoc wrote:Except that isn't quite true ;) ```d struct S {} static assert(S.sizeof <= 1); ```Would scoping 0 initialization to extern(C) struct (or under -betterC) make sense as a compromise?It would break the language into two incompatible dialects. extern(C) is not for semantic differences, it is just to match C calling conventions.
Aug 16
On 8/16/2026 8:52 PM, Richard (Rikki) Andrew Cattermole wrote:
Except that isn't quite true ;)
```d
struct S {}
static assert(S.sizeof <= 1);
```
It's a good point, but it still affects calling conventions because it affects
the size of a struct.
Aug 16
There is something I don't understand here. If an uninitialised float is an error then why does the compiler not just raise it at compile time rather than setting it to a value that is always wrong and letting someone *hopefully* find it at runtime? Even a signalling nan seems like the wrong choice from the start. If the compiler already knows where the problem is because it is the one that adds the nan then just stop compiling right there and let the programmer set it to whatever value they think is sensible. I would be ok with a compiler flag that meant any uninitialised floats were treated as compiler errors so that I could fix them as soon as possible and not end up with a program that just doesn't work as intended. A compiler that silently produces a binary with bugs in it is surely worse isn't it?
Aug 17
On Monday, 17 August 2026 at 07:47:09 UTC, pete wrote:There is something I don't understand here. If an uninitialised float is an error then why does the compiler not just raise it at compile time rather than setting it to a value that is always wrong and letting someone *hopefully* find it at runtime?Change NaN with null and you'll see how that argument doesn't stand. Why would the compiler compile a pointer initialized to null?
Aug 17
On Monday, 17 August 2026 at 10:14:25 UTC, Guillaume Piolat wrote:On Monday, 17 August 2026 at 07:47:09 UTC, pete wrote:I do agree partially with this argument but at least a null will fail hard. Some people may also like the idea of compiler errors for uninitialised pointers. If you want it to start null you can set it explicitly. I am not advocating for this but it doesn't seem outrageous to me. I am in the initialise floats to 0 camp anyway so I am only suggesting this as a compromise solution.There is something I don't understand here. If an uninitialised float is an error then why does the compiler not just raise it at compile time rather than setting it to a value that is always wrong and letting someone *hopefully* find it at runtime?Change NaN with null and you'll see how that argument doesn't stand. Why would the compiler compile a pointer initialized to null?
Aug 17
On 17/08/2026 10:14 PM, Guillaume Piolat wrote:On Monday, 17 August 2026 at 07:47:09 UTC, pete wrote:But it does stand. ```d int* ptr; int val = *ptr; ``` Why should this clearly bad code compile? It shouldn't, and won't with clang or gcc if you turn on warnings. It also won't if you turn on the fast dfa engine. Nullability was first thing to get checked. Default! init floats were like second (it may not be in the next release but it is in ~master). It also has gained a borrow checker to protect reference counting types but Walter is not being helpful in getting it merged.There is something I don't understand here. If an uninitialised float is an error then why does the compiler not just raise it at compile time rather than setting it to a value that is always wrong and letting someone *hopefully* find it at runtime?Change NaN with null and you'll see how that argument doesn't stand. Why would the compiler compile a pointer initialized to null?
Aug 17
On Monday, 17 August 2026 at 07:47:09 UTC, pete wrote:There is something I don't understand here. If an uninitialised float is an error then why does the compiler not just raise it at compile time rather than setting it to a value that is always wrong and letting someone *hopefully* find it at runtime? [...]My understanding is that this would require complex static analysis which is somewhat possible (DFA) put not entirely due to call to extern C functions, or even D functions but linked using a separate compilation mode: ```d extern(C) void v(ref float); void f() { float f; // so init with NaN v(f); // what `v` will do on `f` is not known } ``` That being said, I'm on the zero-init camp too.
Aug 17
On 8/17/2026 12:47 AM, pete wrote:There is something I don't understand here. If an uninitialised float is an error then why does the compiler not just raise it at compile time rather than setting it to a value that is always wrong and letting someone *hopefully* find it at runtime?Because of code like this: ```d float f; if (...) f = 1; else f = 2; ``` If the compiler gave an error for no initializer, the code will look like: ```d float f = 0; // shut up vacuous diagnostic message if (...) f = 1; else f = 2; ``` which is inelegant. Real cases of this tend to be more complex, which leaves the code reviewer with the task of determining why f is explicitly set to 0 when 0 is not the right value for f.
Aug 17
On Tuesday, 18 August 2026 at 03:25:37 UTC, Walter Bright wrote:On 8/17/2026 12:47 AM, pete wrote:I agree this looks a bit inelegant in this example. For more complex code I wouldn't mind at all manually setting f to nan if the compiler could not determine whether all flow paths resulted in f being set. In this case I would expect a code reviewer to also have an issue with it and manually setting it to nan would highlight that there could be a problem. I wouldn't really mind the nan default as long as there was a way of opting out. I would rather the compiler not use poison values if it can just easily ask me how to fix it during the compilation phase. Some people like poison values. Maybe for them the debugging for nan is trivial and that is fine. For some applications it is a pain and the main problem is that sometimes it doesn't even show up until much later.There is something I don't understand here. If an uninitialised float is an error then why does the compiler not just raise it at compile time rather than setting it to a value that is always wrong and letting someone *hopefully* find it at runtime?Because of code like this: ```d float f; if (...) f = 1; else f = 2; ``` If the compiler gave an error for no initializer, the code will look like: ```d float f = 0; // shut up vacuous diagnostic message if (...) f = 1; else f = 2; ``` which is inelegant. Real cases of this tend to be more complex, which leaves the code reviewer with the task of determining why f is explicitly set to 0 when 0 is not the right value for f.
Aug 18
Thank you for your thoughts on this. It would be even better if there was a value that would cause an error immediately upon use. We do have that for pointers! But we don't for floating point (signalling NaNs were discussed elsewhere), so we just have to do our best. BTW, the reason ints default initialize to zero is there is no value we can use as an invalid integer value. Some have proposed int.min, but nothing stops int.min from being part of a calculation and the result is no longer int.min so it is likely far more trouble than it's worth. Designing a programming language is full of compromises. We just have to do the best we can. Unlike C, which uses chars as integer types, D has a distinct char type. And so we can use the "invalid char value", or 0xFF, as its default initializer.
Aug 18
On Tue, Aug 18, 2026 at 12:24:16PM -0700, Walter Bright via Digitalmars-d wrote: [...]Designing a programming language is full of compromises. We just have to do the best we can. Unlike C, which uses chars as integer types, D has a distinct char type. And so we can use the "invalid char value", or 0xFF, as its default initializer.D might as well use integer types for char, because char, wchar, and dchar implicitly convert to non-character int types. This happens even during overload selection: func(int) is preferred over func(dchar) when selecting an overload that calls `func` with a wchar argument. :-( T -- Some crows were looking eagerly at a piece of food in the middle of a busy street and wondering if they should go for it. It's a tempted murder!
Aug 18
On Tuesday, 18 August 2026 at 19:44:49 UTC, H. S. Teoh wrote:D might as well use integer types for char, because char, wchar, and dchar implicitly convert to non-character int types. This happens even during overload selection: func(int) is preferred over func(dchar) when selecting an overload that calls `func` with a wchar argument.No: ```d char f(int) => 'i'; char f(dchar) => 'd'; void main() { import std.stdio; wchar w; w.f.writeln; // Error } ``` ``` charover.d(8): Error: `charover.f` called with argument types `(wchar)` matches multiple overloads after implicit conversions: charover.d(1): `charover.f(int __param_0)` and: charover.d(2): `charover.f(dchar __param_0)` w.f.writeln; ^ ``` I think implicit conversion from integer to character types is a more serious problem than going the other direction: ```d int i = 80; writeln("" ~ i); // prints 'P' ```
Aug 19
On Wednesday, 19 August 2026 at 09:55:56 UTC, Nick Treleaven
wrote:
I think implicit conversion from integer to character types is
a more serious problem than going the other direction:
```d
int i = 80;
writeln("" ~ i); // prints 'P'
```
Sorry, that does error actually - string ~ byte does work:
```d
byte b = 80;
writeln("" ~ b); // prints 'P'
int i = 80;
string s;
s ~= i; // allowed
writeln(""d ~ i); // prints 'P'
```
Aug 19
On Tuesday, August 18, 2026 1:44:49 PM Mountain Daylight Time H. S. Teoh via Digitalmars-d wrote:On Tue, Aug 18, 2026 at 12:24:16PM -0700, Walter Bright via Digitalmars-d wrote: [...]I think that we're still better off with having character types, because it makes the code clearer, it does help with overloading (even if there are still issues), and it helps with character and string literals. However, I completely agree that the character types should not have been treated as integer types at all (so explicit casts would be required to convert them to any integer types), just like I think that bool should never have been an integer type. We're probably stuck at this point though, and at least in the bool case, Walter would never agree to stop treating it as an integer type. The C way of dealing with boolean values is just too deeply ingrained in him at this point. - Jonathan M DavisDesigning a programming language is full of compromises. We just have to do the best we can. Unlike C, which uses chars as integer types, D has a distinct char type. And so we can use the "invalid char value", or 0xFF, as its default initializer.D might as well use integer types for char, because char, wchar, and dchar implicitly convert to non-character int types. This happens even during overload selection: func(int) is preferred over func(dchar) when selecting an overload that calls `func` with a wchar argument. :-(
Aug 19
Casting is a hammer that overrides the type system. Hence one can plausibly argue that every cast is a bug in the program, or at least shows the programmer didn't do a good job selecting types properly. In my own code, I try to select types to minimize a need for casting. Implicit conversions, however, are a "soft" conversion rather than a hammer. C is a bit too loose with that, as such can do hidden truncations. D's design is better because of Value Range Propagation. Before C, I programmed in Wirth's Pascal. It all looked good in the manual, but in practice it was a horrible language. There were no implicit conversions, everything had to be constantly cast back and forth. So the hammer is everywhere. I disliked it strongly, and I think that was a big mistake in Pascal's design. I've also always disliked C's "char" type because it is how one gets a byte integer, having nothing to do with characters. D fixes that. But integral promotions are still retained, because doing integer operations on char's is not that unusual (such as upper/lower case conversions). All in all, D's semantic selections for integral types are better than anyone else's for type safety and convenience.
Aug 19
On Wednesday, 19 August 2026 at 19:57:57 UTC, Walter Bright wrote:All in all, D's semantic selections for integral types are better than anyone else's for type safety and convenience.```d foreach(dchar d; "Über") { writeln(d); } foreach(dchar d; "Über".byCodeUnit) { writeln(d); } ``` The first prints 4 code points, each of the characters listed. The second prints 5 code points, the first two are the *integer promotion* of the two utf8 code units that encode "Ü" to dchar, which is nonsense. The second should not compile. It should be an error to implicitly promote char to dchar. It's a nonsense conversion that is allowed implicitly. Promoting to int is fine. But dchar is not an int. If you think this example is rare, wait until we remove autodecoding. -Steve
Aug 19
On 8/19/2026 2:17 PM, Steven Schveighoffer wrote:```d foreach(dchar d; "Über") { writeln(d); } foreach(dchar d; "Über".byCodeUnit) { writeln(d); } ``` The first prints 4 code points, each of the characters listed. The second prints 5 code points, the first two are the *integer promotion* of the two utf8 code units that encode "Ü" to dchar, which is nonsense.It does what it says on the box - gives 5 code units. The correct code should be: ```d foreach(dchar d; "Über".byDchar) { writeln(d); } ``` byCodeUnit is a building block. The documentation for it says, in part: " Many characters are encoded with multiple code units. For example, the UTF-8 code units for `▒` are `0xC3 0xB8`. That means, an individual element of `byCodeUnit` often does not form a character on its own. Attempting to treat it as one while iterating over the resulting range will give nonsensical results."The second should not compile. It should be an error to implicitly promote char to dchar. It's a nonsense conversion that is allowed implicitly.Didn't H. S. Teoh argue that char should implicitly convert to wchar?Promoting to int is fine. But dchar is not an int. If you think this example is rare, wait until we remove autodecoding.
Aug 19
On Wed, Aug 19, 2026 at 05:37:53PM -0700, Walter Bright via Digitalmars-d wrote:On 8/19/2026 2:17 PM, Steven Schveighoffer wrote:[...][...] I never argued such a thing. I was arguing *against* implicitly converting any char type to an integer type. Yes, it's convenient to be able to do char math without casts, but the kind of bugs that crop up with inadvertent implicit conversion of char types to int is much more costly than this minor convenience. T -- Programming is not just an act of telling a computer what to do: it is also an act of telling other programmers what you wished the computer to do. Both are important, and the latter deserves care. -- Andrew MortonThe second should not compile. It should be an error to implicitly promote char to dchar. It's a nonsense conversion that is allowed implicitly.Didn't H. S. Teoh argue that char should implicitly convert to wchar?
Aug 19
On Thursday, 20 August 2026 at 00:37:53 UTC, Walter Bright wrote:On 8/19/2026 2:17 PM, Steven Schveighoffer wrote:It does not. Given the first statement's behavior, you would expect `dchar` type to mean *re-encode*, as this is what it is doing (this is a special compiler-generated decoding feature). But any char element type other than char arrays int promotes. Subtle changes in meaning for the same syntax are bug factories. This is why I really like `~` being the concat operator instead of `+`. If integer promotion to dchar didn't work, then you would know immediately what the problem is. -Steve```d foreach(dchar d; "Über") { writeln(d); } foreach(dchar d; "Über".byCodeUnit) { writeln(d); } ``` The first prints 4 code points, each of the characters listed. The second prints 5 code points, the first two are the *integer promotion* of the two utf8 code units that encode "Ü" to dchar, which is nonsense.It does what it says on the box - gives 5 code units.
Aug 20
On Wed, Aug 19, 2026 at 12:57:57PM -0700, Walter Bright via Digitalmars-d wrote: [...]I've also always disliked C's "char" type because it is how one gets a byte integer, having nothing to do with characters. D fixes that. But integral promotions are still retained, because doing integer operations on char's is not that unusual (such as upper/lower case conversions).And that is where things go wrong. Upper/lowercasing via arithmetic works only for simplistic languages like English. Other languages require much more sophisticated algorithms (yes, algorithms) to do it correctly. And if you're already doing that, having implicit casting or explicit is no longer a deciding factor. Rather, the incorrectness of having a char literal match an int function over a wchar function becomes a source of bugs.All in all, D's semantic selections for integral types are better than anyone else's for type safety and convenience.Convenience? Better than Pascal? Hardly. As things stand, you have to sprinkle casts everywhere in your D code anyway, if you happen to work with narrow integers. Not much better than Pascal. T -- "I'm running Windows '98." "Yes." "My computer isn't working now." "Yes, you already said that." -- User-Friendly
Aug 19
On 8/19/2026 2:25 PM, H. S. Teoh wrote:And that is where things go wrong. Upper/lowercasing via arithmetic works only for simplistic languages like English. Other languages require much more sophisticated algorithms (yes, algorithms) to do it correctly. And if you're already doing that, having implicit casting or explicit is no longer a deciding factor.Since you don't like the casing example, consider string-to-decimal and decimal-to-string conversions. P.S. I suspect the "simplistic" English is the result of 1) the explosive use of the printing press and 2) morse code and 3) the RADIX50 character set. These were all powerful pressures to simplify the written characters.Rather, the incorrectness of having a char literal match an int function over a wchar function becomes a source of bugs.Function overloading is way overused, and yes, you can get into trouble with integral promotions and not covering the cases properly.You may be using a modern Pascal. I was using an early Pascal that implemented Wirth's "Pascal User Manual and Report". I know that Borland's Turbo Pascal had to add in lots of extensions to make it even possible to write a program in Pascal. For example, the original Pascal had to be all in one file. But there was one gem in Pascal - nested functions. And D has them!All in all, D's semantic selections for integral types are better than anyone else's for type safety and convenience.Convenience? Better than Pascal? Hardly. As things stand, you have to sprinkle casts everywhere in your D code anyway, if you happen to work with narrow integers. Not much better than Pascal.
Aug 19
On Wed, Aug 19, 2026 at 05:01:10PM -0700, Walter Bright via Digitalmars-d wrote:On 8/19/2026 2:25 PM, H. S. Teoh wrote:[...][...] I don't actually use any Pascal (I dislike it for pretty much the same reasons as yours). My point is that current D integer promotion rules make narrow ints a royal pain to work with. A pain on the level of working with casts in Pascal. For example: ```d ubyte x; x++; // OK x += 1; // OK x = x + 1; // NG (WAT?) x = cast(ubyte)(x + 1); // Pascal-level of annoyance ``` And this is just a trivial example. When you have a complex expression involving narrow ints, the level of annoyance quickly becomes unbearable. T -- If anyone wants a copy of Orthopedics Today, I have back issues.Convenience? Better than Pascal? Hardly. As things stand, you have to sprinkle casts everywhere in your D code anyway, if you happen to work with narrow integers. Not much better than Pascal.You may be using a modern Pascal.
Aug 19
On Thursday, 20 August 2026 at 00:01:10 UTC, Walter Bright wrote:On 8/19/2026 2:25 PM, H. S. Teoh wrote:Other countries with less simplistic type systems had their own printing press evolution and had to develop alternatives to things such as morse code. Hell Windows sucks at multilingual use due to the fact that it’s still stuck in pre-Unicode semantics under the hood where each country and language had their own text encoding. Which is why if you get a text document from Iceland it may be misinterpreted as Danish and lead to gibberish text, due to text frequency analysis that windows does being flawed. Japan still clings on to Shift-JIS text encoding in many places which is a fixed-width 16-bit encoding that is incompatible with ASCII and Unicode. Simply because it can represent some things better than the alternatives. So no, it’s more a side effect of US and UK inventors seeing themselves as the center of the world and leaving the rest of us to clean up the mess they made.And that is where things go wrong. Upper/lowercasing via arithmetic works only for simplistic languages like English. Other languages require much more sophisticated algorithms (yes, algorithms) to do it correctly. And if you're already doing that, having implicit casting or explicit is no longer a deciding factor.Since you don't like the casing example, consider string-to-decimal and decimal-to-string conversions. P.S. I suspect the "simplistic" English is the result of 1) the explosive use of the printing press and 2) morse code and 3) the RADIX50 character set. These were all powerful pressures to simplify the written characters.
Aug 20
On Wednesday, August 19, 2026 1:57:57 PM Mountain Daylight Time Walter Bright via Digitalmars-d wrote:Casting is a hammer that overrides the type system. Hence one can plausibly argue that every cast is a bug in the program, or at least shows the programmer didn't do a good job selecting types properly. In my own code, I try to select types to minimize a need for casting. Implicit conversions, however, are a "soft" conversion rather than a hammer. C is a bit too loose with that, as such can do hidden truncations. D's design is better because of Value Range Propagation. Before C, I programmed in Wirth's Pascal. It all looked good in the manual, but in practice it was a horrible language. There were no implicit conversions, everything had to be constantly cast back and forth. So the hammer is everywhere. I disliked it strongly, and I think that was a big mistake in Pascal's design. I've also always disliked C's "char" type because it is how one gets a byte integer, having nothing to do with characters. D fixes that. But integral promotions are still retained, because doing integer operations on char's is not that unusual (such as upper/lower case conversions). All in all, D's semantic selections for integral types are better than anyone else's for type safety and convenience.D has definitely done a better job with type conversions than any other language that I've used, but I also think that it would be better by being stricter with some of its conversions (particularly to integer types). IMHO, there are still too many corner cases where implicit conversions cause subtle issues. So, I do think that we're better off than the competition, but we could do better than we're currently doing. As for explicit casts being an issue, I think that part of the problem is that we only have the one cast operator which tries to do everything, including the really blunt casts that aren't safe. Having std.conv.to helps, because it has a more restricted set of conversions, but it's also overly generalized for many situations where there would ideally be fewer conversions available so that it's much less likely that refactoring would break the code in subtle ways. For instance, the fact that the same cast operator which is used to do a narrowing conversion is also used to do bit casting is a bit of a footgun. It's certainly manageable, but I feel that there are a number of situations where a cast is currently required or would ideally be required where you don't want to have to worry about accidentally reinterpreting the bits of what you're casting. Being able to do something like convert from a floating point type to an integer type with a conversion that's only allowed to work between floating point and integer types rather than trying to convert _any_ type to an integer type would be less error-prone, particularly when refactoring code. I'm not sure that I have a great solution to the problem, but I do think that there's a middle ground between allowing implicit conversions and using the cast operator. In some cases, it would probably be a good idea to provide functions to do specific types of conversions in a checked manner (e.g. only allowing a specific subset of conversions based on a template constraint), but I've also sometimes thought that it would be nice to have an explicit implicit cast (for lack of a better term) where there's only a specific set of conversions that are allowed (similar to what you get with an implicit conversion now), but it's explicit. Perhaps explicit construction would be one way to do that, or some other operator could be introduced. So, for instance, let's say you could do something like `int('A')` but `int i = 'A';` would be illegal, and a function that accepted int wouldn't accept char. That way, you wouldn't need to use `cast(int) foo` and risk accidentally doing a bit cast on some other type when the code was refactored, and the type of foo changed from something with a sensible conversion to int to something that did a bit cast in order to be converted to int. I'm not currently proposing that we make any such changes in D (and even if we wanted to, we'd have to be very careful about it because of all of the existing code which allows a variety of implicit conversions that we would ideally restrict), but there's no question that if I were to create my own language, I'd reduce the number of implicit conversions in comparison to what D has, and I'd provide ways to convert types which did not involve a cast operator which could do any sort of unsafe cast. IMHO, D's cast operator just does way too much and makes it far too easy to do one type of cast when you intended to do a different one - and/or to have the type of cast changee in unintended ways when code is refactored. - Jonathan M Davis
Aug 19
On 18/08/2026 7:16 PM, pete wrote:I agree this looks a bit inelegant in this example. For more complex code I wouldn't mind at all manually setting f to nan if the compiler could not determine whether all flow paths resulted in f being set. In this case I would expect a code reviewer to also have an issue with it and manually setting it to nan would highlight that there could be a problem. I wouldn't really mind the nan default as long as there was a way of opting out. I would rather the compiler not use poison values if it can just easily ask me how to fix it during the compilation phase. Some people like poison values. Maybe for them the debugging for nan is trivial and that is fine. For some applications it is a pain and the main problem is that sometimes it doesn't even show up until much later.I'm ok with this, however this is going to be a pretty invasive change and its stops being simply a static analysis feature of the compiler. Its a good example of why I'm not writing out the exact behavior of the fastdfa engine, I want people to interpret the results of their experience and judge when they think it should or shouldn't be activating, because it is dependent on the user base on how it should be configured. For these kinds of problems its a sociological problem to what extent people are willing put up with false positives.
Aug 18
On Tuesday, 18 August 2026 at 03:25:37 UTC, Walter Bright wrote:On 8/17/2026 12:47 AM, pete wrote:Regardless of how the value `f` is initialzed, this style has a problem: The initial value of `f` is discarded. I think that discarding values shall be avoided. Thus I write the initialization: ```d float f = (...) ? 1 : 2; ``` Compiler warnings/errors like "Defined but not used" are known for variables. Is there a similar facility for values?There is something I don't understand here. If an uninitialised float is an error then why does the compiler not just raise it at compile time rather than setting it to a value that is always wrong and letting someone *hopefully* find it at runtime?Because of code like this: ```d float f; if (...) f = 1; else f = 2; ```
Aug 19
On Saturday, 15 August 2026 at 06:11:23 UTC, Walter Bright wrote:On 8/14/2026 2:25 PM, Steven Schveighoffer wrote:1. If this was the correct value, I would initialize it to 0.001. What if the correct value is 0.001 and you accidentally use 0.01? 2. If you forgot, the chances of 0 not showing up somewhere are slim. If it's supposed to be a factor, all of a sudden all your values are unexpectedly 0. If it's supposed to be an epsilon, then most likely your code fails to work correctly. If it's supposed to be an addition factor, then likely 0 is close enough that it's not important, or it makes a difference and you notice. 3. NaN isn't significantly more likely to be seen than erroneous 0. Most code that uses floats doesn't print them. NaN has weird properties. Maybe it's used in a comparison, and is always false. How is that obvious? Ever see NaN show up on a UI? How is that possible since NaN is so obvious to the developer they would have fixed it before release? 4. I would actually be *OK* with NaN as a default if it failed on first use. The problem with it is that it propagates far away from the actual error. Null is different, it fails immediately and loudly. 5. What about ints? Sometimes the default value of 0 is not right, and it should be 1. How do we cope with programming when ints default to 0? 0 is a better default, a consistent default, an expected default, and good default values make programming more pleasant.In all the years I have used D, whenever I have forgotten to initialize a floating point number, the fix was ALWAYS to initialize explicitly to 0, because that's what I expected and desired to happen.Yes, initializing to 0.0 is very common. And that works fine until the correct initialization is 0.001, and there's an unrecognized bug in the output.This is just hypothesizing. If 0 isn't the right value, then most likely you will see the error. Show some real world examples of NaN showing up when *erroneous* 0 would not have. In all my cases, NaN shows up because it *should have been* 0.This is a big stain on D, and it disrupts everyone's work unnecessarily. The problem is the distance from the error to the result.The problem with default initialization to 0.0 is not recognizing that the result is in error, which I submit is much much worse. It costs orders of magnitude less money to fix a bug made very visible with a NaN output than output that is just slightly wrong and unnoticed out in the field.When reviewing code, and you see: ```d float f; ``` is the intention to initialize it to zero, or did the programmer simply forget to initialize it? I've had more than enough of the latter in actual code.```d int i; ``` Same thing. In D, it is reasonable to expect a 0 init for a declared variable. I use it all the time. If you are used to C, yeah, the default (random data) is bad. Note that at least C has `= {0}` which allows you to zero everything in a struct regardless of nested data structure. D doesn't have this.P.S. In case it isn't obvious, this derives from my experience designing flight controls for the 757. You really really really want to find all the bugs before cutting metal or, heaven forbid, trying to lift it off the runway. Inconvenience be damned.It's not obvious how this is relevant. NaN's are in actual released code, I've seen them. They do not magically expose all errors. What prevents errors is actual good tests. And you can always init to NaN explicitly if you want, just like today you can init to 0 if you want. 0 being correct is way way way more likely than NaN exposing a bug that an erroneous default 0 would not. This just makes for more busywork for the developer, for zero benefit. -Steve
Aug 16
Thank you for the excellent summary of your question. I believe I have responded to all these points at one point or another in this thread, so repeating it ad nauseam just will go nowhere. Hence, with DConf coming up, I recommend we have a discussion on this over a beer! And, of course, anyone else can join us!
Aug 16
On 17/08/2026 3:58 PM, Walter Bright wrote:Thank you for the excellent summary of your question. I believe I have responded to all these points at one point or another in this thread, so repeating it ad nauseam just will go nowhere. Hence, with DConf coming up, I recommend we have a discussion on this over a beer! And, of course, anyone else can join us!Sounds like a lightning talk to me.
Aug 16
On Friday, 14 August 2026 at 05:57:55 UTC, ABrightLight wrote:Hello. I understand this subject's been discussed a number of times before, but I'd like to throw in my reasoning for why it would benefit us more for floats to initialize to 0 than NaN.There is nothing to "fix" because NaN init is the right choice. I work in float all the time (audio) and this "issue" is not even an issue, when I happen to have a NaN bug I'm actually glad I can track it down so easily thanks to its stickyness. There are lot of things I'd want out of D floating point way before that: - A way to warn for downcasts from double to float like -vtls. Domain-specific use but very much relevant. - Making "fast math" options illegal, as they are enticing, vague and very dangerous. - `real` could disappear, again this has been debated for days with no point. It doesn't hurt eigher to be here... just line NaN init.
Aug 16
On Friday, 14 August 2026 at 05:57:55 UTC, ABrightLight wrote:2. It is argued that since, like pointers that have `null` and are default initialized to this, floats should also initialize to its version of `null`. However this is a false equivalence since the use of a null pointer is specified/standardized to crash the program due to a concern for memory safety (it's not even set to undefined behavior, a program halt must occur). The same memory safety concern is not present for most operations relying on floats, and the existence of NaN being left without a crash [or even an exception thrown] is to cater to performance.I don't think so. Using NaN will result in another NaN, so eventually the error will show up, unless you end up discarding the value and not using it anyhow. Just as good as aborting immediately. Well, except for casts and comparison operators. IMO there should be an error if you try to compare a NaN to anything or cast it to an integer. Currently those cases are what lead to silent failures.
Aug 17
On Friday, 14 August 2026 at 05:57:55 UTC, ABrightLight wrote:Hello. I understand this subject's been discussed a number of times before, but I'd like to throw in my reasoning for why it would benefit us more for floats to initialize to 0 than NaN. 1. float is generally used for numeric computation (things like NaN boxing are examples of uses outside of this) and as such have similarity to the integer types (they will even implicitly coerce mathematical operations to float). Since integers default to 0, floats should too. 1a. It may be argued that integers only default to 0 because there is no meaningful "null" value, but in my opinion this is not convincing because I think that most people would opt for them getting a reasonable default value right from the start instead of being forced to `= 0;` It is very common to see loop variables and other forms just say `int i;` or similar, and no one is confused by this. 2. It is argued that since, like pointers that have `null` and are default initialized to this, floats should also initialize to its version of `null`. However this is a false equivalence since the use of a null pointer is specified/standardized to crash the program due to a concern for memory safety (it's not even set to undefined behavior, a program halt must occur). The same memory safety concern is not present for most operations relying on floats, and the existence of NaN being left without a crash [or even an exception thrown] is to cater to performance. For cases where debugging by program halt is required, most of the time the approach done is for a compiler switch to allow throwing an exception instead of just halting the program, since a stack trace is presumed to be desired. 3. I know that rikki's DFA implementation will be able to detect when a `float x;` occurs without then being actually initialized to something useful (keep up the great work rikki!), but this particular feature is a special case that is not exactly within scope. And the fact that this is even being added as a special case should be a hint that leaving NaN as the default init is much less useful than some integer-compatible value like 0. P.S. This subject is a bit subjective (no pun intended) but overall we'd likely see more user satisfaction from the float init switch. And from what I could tell, it's been well received by the OpenD folks, so there's already been a bit of a testbed for this.The debate is treating a symptom-management mechanism as though it were an invariant-enforcement mechanism. float.init == 0 vs float.init == NaN is somewhat of a distraction. A sentinel value is not the same thing as an invariant. The default value can absolutely affect how bugs manifest, but you should not be relying on a language's default initialization to establish a semantic invariant. The default value is irrelevant to establishing that invariant. Better to rely on the relationship between a value and the meaning the next operation assumes it has. That's the more fundamental issue here: not whether the default value is 0 or NaN, but whether the value still means what the operation consuming it assumes it means. Interestingly, that is what this book, 'The Wrong Memory', is all about. The dangerous bug isn't necessarily the wrong value, but the moment when a value stops meaning what we think it means. https://strawberry9.github.io/the-wrong-memory/cover.html
Aug 20









Mindy Batek (0xEAB) <desisma heidel.beer> 