Your example:

    float f;
    if (condition1)
        f = 7;
    ... code ...
    if (condition2)
        ++f;

is flawed in that condition1 is _required_ to pass in sync with condition2, or you'll get a NaN in the result. In this scenario, you're forced to provide a usable default explicitly no matter what, so your later argument:

"This leads to the programmer getting annoyed with false positive error diagnostics, and he'll likely add an =0"

doesn't make sense, because he needs to provide a usable value in the first place.


This is exactly why I was arguing that explicit assignment to NaN was better for debugging as well. Because a maintenance programmer, that steps in at a later date, would:

1. be less likely to change an explicit assignment to NaN without understand the code fully first.

2. have an easier time tracking down the origin of a NaN error, because variables not explicitly assigned to NaN _can't_ be the culprit.

Imagine we have code that looks like:

    class SomeClass
    {
        float foo;
        float bobDole;
        float someKind;
        float barFoo = float.nan;
        float aVariable;
        float barBaz;

        this() { ... lotsa init code ... }
    }

If floats defaulted to 0.0f, then we'd know exactly which variable to analyze in order to find the source of our NaN bug: 'barFoo'. Since we don't have this visual clue, we have to analyze all of them. Of course, we can reverse this by explicitly assigning all, except 'barFoo', to 0.0f, but that's:

1. less convenient to type
2. harder to visually parse to find the potential NaNs
3. inconsistent with 'int'




This is how I wish D worked:

1. Functions:

    void foo() {
        float f;
        f ++; // compiler error
    }

    void foo() {
        float f;
        if (condition1)
            f = 5;
        if (condition2)
            f ++; // compiler error
    }

2. Structs & Classes:

    class Foo {
        float f; // 0.0f
        void bar() { f++; }
        // Notice: no constructor defined
    }

    void main() {
        auto foo = new Foo();
        foo.bar(); // works fine
    }


Unfortunately, structs don't have default constructors in D. I'm not sure exactly why that is, but if there's some design or performance issue, structs could always work like this instead:

3. Structs:

    struct Foo {
        float f; // compiler error
    }

    struct Foo {
        float f = 0; // OK
    }

    struct Foo {
        float f; // OK, if:
        this() { f = 0; } // set in constructor
    }

Reply via email to